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 | |
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
-rw-r--r-- | chromeos/chromeos.gyp | 9 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.cc | 22 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.h | 12 | ||||
-rw-r--r-- | chromeos/dbus/flimflam_device_client.cc | 17 | ||||
-rw-r--r-- | chromeos/dbus/flimflam_manager_client.cc | 4 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client.cc | 6 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client.h | 6 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client_unittest.cc | 2 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.cc | 8 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.h | 12 | ||||
-rw-r--r-- | chromeos/dbus/mock_gsm_sms_client.h | 2 | ||||
-rw-r--r-- | chromeos/dbus/mock_modem_messaging_client.cc | 13 | ||||
-rw-r--r-- | chromeos/dbus/mock_modem_messaging_client.h | 40 | ||||
-rw-r--r-- | chromeos/dbus/mock_sms_client.cc | 13 | ||||
-rw-r--r-- | chromeos/dbus/mock_sms_client.h | 29 | ||||
-rw-r--r-- | chromeos/dbus/modem_messaging_client.cc | 278 | ||||
-rw-r--r-- | chromeos/dbus/modem_messaging_client.h | 73 | ||||
-rw-r--r-- | chromeos/dbus/modem_messaging_client_unittest.cc | 248 | ||||
-rw-r--r-- | chromeos/dbus/sms_client.cc | 130 | ||||
-rw-r--r-- | chromeos/dbus/sms_client.h | 57 |
20 files changed, 974 insertions, 7 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 68ea8d7..4ab0e3c 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -85,6 +85,8 @@ 'dbus/image_burner_client.h', 'dbus/introspectable_client.cc', 'dbus/introspectable_client.h', + 'dbus/modem_messaging_client.cc', + 'dbus/modem_messaging_client.h', 'dbus/power_manager_client.cc', 'dbus/power_manager_client.h', 'dbus/power_supply_status.cc', @@ -93,6 +95,8 @@ 'dbus/session_manager_client.h', 'dbus/speech_synthesizer_client.cc', 'dbus/speech_synthesizer_client.h', + 'dbus/sms_client.cc', + 'dbus/sms_client.h', 'dbus/update_engine_client.cc', 'dbus/update_engine_client.h', 'monitor/output_configurator.cc', @@ -158,10 +162,14 @@ 'dbus/mock_image_burner_client.h', 'dbus/mock_introspectable_client.cc', 'dbus/mock_introspectable_client.h', + 'dbus/mock_modem_messaging_client.cc', + 'dbus/mock_modem_messaging_client.h', 'dbus/mock_power_manager_client.cc', 'dbus/mock_power_manager_client.h', 'dbus/mock_session_manager_client.cc', 'dbus/mock_session_manager_client.h', + 'dbus/mock_sms_client.cc', + 'dbus/mock_sms_client.h', 'dbus/mock_speech_synthesizer_client.cc', 'dbus/mock_speech_synthesizer_client.h', 'dbus/mock_update_engine_client.cc', @@ -202,6 +210,7 @@ 'dbus/ibus/ibus_text_unittest.cc', 'dbus/ibus/ibus_input_context_client_unittest.cc', 'dbus/introspectable_client_unittest.cc', + 'dbus/modem_messaging_client_unittest.cc', 'network/network_sms_handler_unittest.cc', ], 'include_dirs': [ diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index 8303bbb..cc35a9a 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc @@ -29,8 +29,10 @@ #include "chromeos/dbus/ibus/ibus_input_context_client.h" #include "chromeos/dbus/image_burner_client.h" #include "chromeos/dbus/introspectable_client.h" +#include "chromeos/dbus/modem_messaging_client.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/session_manager_client.h" +#include "chromeos/dbus/sms_client.h" #include "chromeos/dbus/speech_synthesizer_client.h" #include "chromeos/dbus/update_engine_client.h" #include "dbus/bus.h" @@ -104,7 +106,7 @@ class DBusThreadManagerImpl : public DBusThreadManager { // Create the Flimflam Service client. flimflam_service_client_.reset( FlimflamServiceClient::Create(client_type, system_bus_.get())); - // Create the SMS cilent. + // Create the Gsm SMS client. gsm_sms_client_.reset( GsmSMSClient::Create(client_type, system_bus_.get())); // Create the image burner client. @@ -113,12 +115,18 @@ class DBusThreadManagerImpl : public DBusThreadManager { // Create the introspectable object client. introspectable_client_.reset( IntrospectableClient::Create(client_type, system_bus_.get())); + // Create the ModemMessaging client. + modem_messaging_client_.reset( + ModemMessagingClient::Create(client_type, system_bus_.get())); // Create the power manager client. power_manager_client_.reset( PowerManagerClient::Create(client_type_maybe_stub, system_bus_.get())); // Create the session manager client. session_manager_client_.reset( SessionManagerClient::Create(client_type, system_bus_.get())); + // Create the SMS client. + sms_client_.reset( + SMSClient::Create(client_type, system_bus_.get())); // Create the speech synthesizer client. speech_synthesizer_client_.reset( SpeechSynthesizerClient::Create(client_type, system_bus_.get())); @@ -265,6 +273,11 @@ class DBusThreadManagerImpl : public DBusThreadManager { } // DBusThreadManager override. + virtual ModemMessagingClient* GetModemMessagingClient() OVERRIDE { + return modem_messaging_client_.get(); + } + + // DBusThreadManager override. virtual PowerManagerClient* GetPowerManagerClient() OVERRIDE { return power_manager_client_.get(); } @@ -275,6 +288,11 @@ class DBusThreadManagerImpl : public DBusThreadManager { } // DBusThreadManager override. + virtual SMSClient* GetSMSClient() OVERRIDE { + return sms_client_.get(); + } + + // DBusThreadManager override. virtual SpeechSynthesizerClient* GetSpeechSynthesizerClient() OVERRIDE { return speech_synthesizer_client_.get(); } @@ -315,8 +333,10 @@ class DBusThreadManagerImpl : public DBusThreadManager { scoped_ptr<GsmSMSClient> gsm_sms_client_; scoped_ptr<ImageBurnerClient> image_burner_client_; scoped_ptr<IntrospectableClient> introspectable_client_; + scoped_ptr<ModemMessagingClient> modem_messaging_client_; scoped_ptr<PowerManagerClient> power_manager_client_; scoped_ptr<SessionManagerClient> session_manager_client_; + scoped_ptr<SMSClient> sms_client_; scoped_ptr<SpeechSynthesizerClient> speech_synthesizer_client_; scoped_ptr<UpdateEngineClient> update_engine_client_; scoped_ptr<IBusClient> ibus_client_; diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index 8e6991b..3a69528 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h @@ -43,8 +43,10 @@ class IBusClient; class IBusInputContextClient; class ImageBurnerClient; class IntrospectableClient; +class ModemMessagingClient; class PowerManagerClient; class SessionManagerClient; +class SMSClient; class SpeechSynthesizerClient; class UpdateEngineClient; @@ -189,6 +191,11 @@ class CHROMEOS_EXPORT DBusThreadManager { // down. virtual IntrospectableClient* GetIntrospectableClient() = 0; + // Returns the Modem Messaging client, owned by DBusThreadManager. + // Do not cache this pointer and use it after DBusThreadManager is shut + // down. + virtual ModemMessagingClient* GetModemMessagingClient() = 0; + // Returns the power manager client, owned by DBusThreadManager. // See also comments at session_manager_client(). virtual PowerManagerClient* GetPowerManagerClient() = 0; @@ -198,6 +205,11 @@ class CHROMEOS_EXPORT DBusThreadManager { // down. virtual SessionManagerClient* GetSessionManagerClient() = 0; + // Returns the SMS client, owned by DBusThreadManager. + // Do not cache this pointer and use it after DBusThreadManager is shut + // down. + virtual SMSClient* GetSMSClient() = 0; + // Returns the speech synthesizer client, owned by DBusThreadManager. // Do not cache this pointer and use it after DBusThreadManager is shut // down. diff --git a/chromeos/dbus/flimflam_device_client.cc b/chromeos/dbus/flimflam_device_client.cc index 12cd522..f16189f 100644 --- a/chromeos/dbus/flimflam_device_client.cc +++ b/chromeos/dbus/flimflam_device_client.cc @@ -225,6 +225,23 @@ class FlimflamDeviceClientStubImpl : public FlimflamDeviceClient { flimflam::kDBusObjectProperty, base::Value::CreateStringValue("/device/cellular1")); stub_devices_.Set(kStubCellular1, cellular_properties); + + // Create a second device stubbing a modem managed by + // ModemManager1 interfaces. + // Note: name matches Manager entry. + const char kStubCellular2[] = "stub_cellular2"; + cellular_properties = new base::DictionaryValue; + cellular_properties->SetWithoutPathExpansion( + flimflam::kTypeProperty, + base::Value::CreateStringValue(flimflam::kTypeCellular)); + cellular_properties->SetWithoutPathExpansion( + flimflam::kDBusConnectionProperty, + base::Value::CreateStringValue(":stub.0")); + cellular_properties->SetWithoutPathExpansion( + flimflam::kDBusObjectProperty, + base::Value::CreateStringValue( + "/org/freedesktop/ModemManager1/stub/0")); + stub_devices_.Set(kStubCellular2, cellular_properties); } virtual ~FlimflamDeviceClientStubImpl() {} diff --git a/chromeos/dbus/flimflam_manager_client.cc b/chromeos/dbus/flimflam_manager_client.cc index 2bd1869..4bbc131f 100644 --- a/chromeos/dbus/flimflam_manager_client.cc +++ b/chromeos/dbus/flimflam_manager_client.cc @@ -149,9 +149,11 @@ class FlimflamManagerClientStubImpl : public FlimflamManagerClient { public: FlimflamManagerClientStubImpl() : weak_ptr_factory_(this) { base::ListValue* device_list = new base::ListValue; - // Note: name matches Device stub map. + // Note: names match Device stub map. const char kStubCellular1[] = "stub_cellular1"; + const char kStubCellular2[] = "stub_cellular2"; device_list->Append(base::Value::CreateStringValue(kStubCellular1)); + device_list->Append(base::Value::CreateStringValue(kStubCellular2)); stub_properties_.Set(flimflam::kDevicesProperty, device_list); } diff --git a/chromeos/dbus/gsm_sms_client.cc b/chromeos/dbus/gsm_sms_client.cc index 4eea344..2836605 100644 --- a/chromeos/dbus/gsm_sms_client.cc +++ b/chromeos/dbus/gsm_sms_client.cc @@ -3,6 +3,10 @@ // found in the LICENSE file. #include "chromeos/dbus/gsm_sms_client.h" +#include <map> +#include <utility> +#include <vector> + #include "base/bind.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" @@ -21,7 +25,7 @@ namespace chromeos { namespace { // A class actually making method calls for SMS services, used by -// GsmSMSClietnImpl. +// GsmSMSClientImpl. class SMSProxy { public: typedef GsmSMSClient::SmsReceivedHandler SmsReceivedHandler; diff --git a/chromeos/dbus/gsm_sms_client.h b/chromeos/dbus/gsm_sms_client.h index 537b4e4..68d8275 100644 --- a/chromeos/dbus/gsm_sms_client.h +++ b/chromeos/dbus/gsm_sms_client.h @@ -25,7 +25,7 @@ class ObjectPath; namespace chromeos { -// GsmSMSClient is used to communicate with +// GsmSMSClient is used to communicate with the // org.freedesktop.ModemManager.Modem.Gsm.SMS service. // All methods should be called from the origin thread (UI thread) which // initializes the DBusThreadManager instance. @@ -43,12 +43,12 @@ class CHROMEOS_EXPORT GsmSMSClient { static GsmSMSClient* Create(DBusClientImplementationType type, dbus::Bus* bus); - // Sets DataPlansUpdate signal handler. + // Sets SmsReceived signal handler. virtual void SetSmsReceivedHandler(const std::string& service_name, const dbus::ObjectPath& object_path, const SmsReceivedHandler& handler) = 0; - // Resets DataPlansUpdate signal handler. + // Resets SmsReceived signal handler. virtual void ResetSmsReceivedHandler(const std::string& service_name, const dbus::ObjectPath& object_path) = 0; diff --git a/chromeos/dbus/gsm_sms_client_unittest.cc b/chromeos/dbus/gsm_sms_client_unittest.cc index 6cbd5fd..49aba66 100644 --- a/chromeos/dbus/gsm_sms_client_unittest.cc +++ b/chromeos/dbus/gsm_sms_client_unittest.cc @@ -312,7 +312,7 @@ TEST_F(GsmSMSClientTest, List) { kTextKey, base::Value::CreateStringValue(kExampleText)); expected_result.Append(sms); expected_result_ = &expected_result; - // Call Delete. + // Call List. client_->List(kServiceName, dbus::ObjectPath(kObjectPath), base::Bind(&MockListCallback::Run, base::Unretained(&callback))); diff --git a/chromeos/dbus/mock_dbus_thread_manager.cc b/chromeos/dbus/mock_dbus_thread_manager.cc index 2fb1b68..2db9c66 100644 --- a/chromeos/dbus/mock_dbus_thread_manager.cc +++ b/chromeos/dbus/mock_dbus_thread_manager.cc @@ -24,8 +24,10 @@ #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_modem_messaging_client.h" #include "chromeos/dbus/mock_power_manager_client.h" #include "chromeos/dbus/mock_session_manager_client.h" +#include "chromeos/dbus/mock_sms_client.h" #include "chromeos/dbus/mock_speech_synthesizer_client.h" #include "chromeos/dbus/mock_update_engine_client.h" @@ -54,8 +56,10 @@ MockDBusThreadManager::MockDBusThreadManager() mock_gsm_sms_client_(new MockGsmSMSClient), mock_image_burner_client_(new MockImageBurnerClient), mock_introspectable_client_(new MockIntrospectableClient), + mock_modem_messaging_client_(new MockModemMessagingClient), mock_power_manager_client_(new MockPowerManagerClient), mock_session_manager_client_(new MockSessionManagerClient), + mock_sms_client_(new MockSMSClient), mock_speech_synthesizer_client_(new MockSpeechSynthesizerClient), mock_update_engine_client_(new MockUpdateEngineClient), mock_ibus_client_(new MockIBusClient), @@ -96,10 +100,14 @@ MockDBusThreadManager::MockDBusThreadManager() .WillRepeatedly(Return(mock_image_burner_client())); EXPECT_CALL(*this, GetIntrospectableClient()) .WillRepeatedly(Return(mock_introspectable_client())); + EXPECT_CALL(*this, GetModemMessagingClient()) + .WillRepeatedly(Return(mock_modem_messaging_client())); EXPECT_CALL(*this, GetPowerManagerClient()) .WillRepeatedly(Return(mock_power_manager_client_.get())); EXPECT_CALL(*this, GetSessionManagerClient()) .WillRepeatedly(Return(mock_session_manager_client_.get())); + EXPECT_CALL(*this, GetSMSClient()) + .WillRepeatedly(Return(mock_sms_client_.get())); EXPECT_CALL(*this, GetSpeechSynthesizerClient()) .WillRepeatedly(Return(mock_speech_synthesizer_client_.get())); EXPECT_CALL(*this, GetUpdateEngineClient()) diff --git a/chromeos/dbus/mock_dbus_thread_manager.h b/chromeos/dbus/mock_dbus_thread_manager.h index 9d015e8..6a1a12d 100644 --- a/chromeos/dbus/mock_dbus_thread_manager.h +++ b/chromeos/dbus/mock_dbus_thread_manager.h @@ -38,8 +38,10 @@ class MockIBusClient; class MockIBusInputContextClient; class MockImageBurnerClient; class MockIntrospectableClient; +class MockModemMessagingClient; class MockPowerManagerClient; class MockSessionManagerClient; +class MockSMSClient; class MockSpeechSynthesizerClient; class MockUpdateEngineClient; @@ -72,8 +74,10 @@ class MockDBusThreadManager : public DBusThreadManager { MOCK_METHOD0(GetGsmSMSClient, GsmSMSClient*(void)); MOCK_METHOD0(GetImageBurnerClient, ImageBurnerClient*(void)); MOCK_METHOD0(GetIntrospectableClient, IntrospectableClient*(void)); + MOCK_METHOD0(GetModemMessagingClient, ModemMessagingClient*(void)); MOCK_METHOD0(GetPowerManagerClient, PowerManagerClient*(void)); MOCK_METHOD0(GetSessionManagerClient, SessionManagerClient*(void)); + MOCK_METHOD0(GetSMSClient, SMSClient*(void)); MOCK_METHOD0(GetSpeechSynthesizerClient, SpeechSynthesizerClient*(void)); MOCK_METHOD0(GetUpdateEngineClient, UpdateEngineClient*(void)); MOCK_METHOD0(GetIBusClient, IBusClient*(void)); @@ -133,12 +137,18 @@ class MockDBusThreadManager : public DBusThreadManager { MockIntrospectableClient* mock_introspectable_client() { return mock_introspectable_client_.get(); } + MockModemMessagingClient* mock_modem_messaging_client() { + return mock_modem_messaging_client_.get(); + } MockPowerManagerClient* mock_power_manager_client() { return mock_power_manager_client_.get(); } MockSessionManagerClient* mock_session_manager_client() { return mock_session_manager_client_.get(); } + MockSMSClient* mock_sms_client() { + return mock_sms_client_.get(); + } MockSpeechSynthesizerClient* mock_speech_synthesizer_client() { return mock_speech_synthesizer_client_.get(); } @@ -171,8 +181,10 @@ class MockDBusThreadManager : public DBusThreadManager { scoped_ptr<MockGsmSMSClient> mock_gsm_sms_client_; scoped_ptr<MockImageBurnerClient> mock_image_burner_client_; scoped_ptr<MockIntrospectableClient> mock_introspectable_client_; + scoped_ptr<MockModemMessagingClient> mock_modem_messaging_client_; scoped_ptr<MockPowerManagerClient> mock_power_manager_client_; scoped_ptr<MockSessionManagerClient> mock_session_manager_client_; + scoped_ptr<MockSMSClient> mock_sms_client_; scoped_ptr<MockSpeechSynthesizerClient> mock_speech_synthesizer_client_; scoped_ptr<MockUpdateEngineClient> mock_update_engine_client_; scoped_ptr<MockIBusClient> mock_ibus_client_; diff --git a/chromeos/dbus/mock_gsm_sms_client.h b/chromeos/dbus/mock_gsm_sms_client.h index b7078d2..493d4bd 100644 --- a/chromeos/dbus/mock_gsm_sms_client.h +++ b/chromeos/dbus/mock_gsm_sms_client.h @@ -6,6 +6,8 @@ #define CHROMEOS_DBUS_MOCK_GSM_SMS_CLIENT_H_ #pragma once +#include <string> + #include "base/values.h" #include "chromeos/dbus/gsm_sms_client.h" #include "dbus/object_path.h" diff --git a/chromeos/dbus/mock_modem_messaging_client.cc b/chromeos/dbus/mock_modem_messaging_client.cc new file mode 100644 index 0000000..6301d07 --- /dev/null +++ b/chromeos/dbus/mock_modem_messaging_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_modem_messaging_client.h" + +namespace chromeos { + +MockModemMessagingClient::MockModemMessagingClient() {} + +MockModemMessagingClient::~MockModemMessagingClient() {} + +} // namespace chromeos diff --git a/chromeos/dbus/mock_modem_messaging_client.h b/chromeos/dbus/mock_modem_messaging_client.h new file mode 100644 index 0000000..6159ff5 --- /dev/null +++ b/chromeos/dbus/mock_modem_messaging_client.h @@ -0,0 +1,40 @@ +// 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_MODEM_MESSAGING_CLIENT_H_ +#define CHROMEOS_DBUS_MOCK_MODEM_MESSAGING_CLIENT_H_ +#pragma once + +#include <string> + +#include "base/values.h" +#include "chromeos/dbus/modem_messaging_client.h" +#include "dbus/object_path.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace chromeos { + +class MockModemMessagingClient : public ModemMessagingClient { + public: + MockModemMessagingClient(); + virtual ~MockModemMessagingClient(); + + 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, + const dbus::ObjectPath& sms_path, + const DeleteCallback& callback)); + MOCK_METHOD3(List, void(const std::string& service_name, + const dbus::ObjectPath& object_path, + const ListCallback& callback)); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_MOCK_MODEM_MESSAGING_CLIENT_H_ diff --git a/chromeos/dbus/mock_sms_client.cc b/chromeos/dbus/mock_sms_client.cc new file mode 100644 index 0000000..0a62dcc --- /dev/null +++ b/chromeos/dbus/mock_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_sms_client.h" + +namespace chromeos { + +MockSMSClient::MockSMSClient() {} + +MockSMSClient::~MockSMSClient() {} + +} // namespace chromeos diff --git a/chromeos/dbus/mock_sms_client.h b/chromeos/dbus/mock_sms_client.h new file mode 100644 index 0000000..da6d0d7 --- /dev/null +++ b/chromeos/dbus/mock_sms_client.h @@ -0,0 +1,29 @@ +// 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_SMS_CLIENT_H_ +#define CHROMEOS_DBUS_MOCK_SMS_CLIENT_H_ +#pragma once + +#include <string> + +#include "base/values.h" +#include "chromeos/dbus/sms_client.h" +#include "dbus/object_path.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace chromeos { + +class MockSMSClient : public SMSClient { + public: + MockSMSClient(); + virtual ~MockSMSClient(); + MOCK_METHOD3(GetAll, void(const std::string& service_name, + const dbus::ObjectPath& object_path, + const GetAllCallback& callback)); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_MOCK_SMS_CLIENT_H_ 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 diff --git a/chromeos/dbus/modem_messaging_client.h b/chromeos/dbus/modem_messaging_client.h new file mode 100644 index 0000000..00607ad --- /dev/null +++ b/chromeos/dbus/modem_messaging_client.h @@ -0,0 +1,73 @@ +// 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_MODEM_MESSAGING_CLIENT_H_ +#define CHROMEOS_DBUS_MODEM_MESSAGING_CLIENT_H_ +#pragma once + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "chromeos/chromeos_export.h" +#include "chromeos/dbus/dbus_client_implementation_type.h" + +namespace dbus { +class Bus; +class ObjectPath; +} + +namespace chromeos { + +// ModemMessagingClient is used to communicate with the +// org.freedesktop.ModemManager1.Modem.Messaging service. All methods +// should be called from the origin thread (UI thread) which +// initializes the DBusThreadManager instance. +class CHROMEOS_EXPORT ModemMessagingClient { + public: + typedef base::Callback<void()> DeleteCallback; + typedef base::Callback<void(const dbus::ObjectPath& message_path, + bool complete)> SmsReceivedHandler; + typedef base::Callback<void(const std::vector<dbus::ObjectPath>& paths)> + ListCallback; + + virtual ~ModemMessagingClient(); + + // Factory function, creates a new instance and returns ownership. + // For normal usage, access the singleton via DBusThreadManager::Get(). + static ModemMessagingClient* Create(DBusClientImplementationType type, + dbus::Bus* bus); + + // Sets SmsReceived signal handler. + virtual void SetSmsReceivedHandler(const std::string& service_name, + const dbus::ObjectPath& object_path, + const SmsReceivedHandler& handler) = 0; + + // Resets SmsReceived 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, + const dbus::ObjectPath& sms_path, + const DeleteCallback& 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. + ModemMessagingClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(ModemMessagingClient); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_MODEM_MESSAGING_CLIENT_H_ diff --git a/chromeos/dbus/modem_messaging_client_unittest.cc b/chromeos/dbus/modem_messaging_client_unittest.cc new file mode 100644 index 0000000..8f5a026 --- /dev/null +++ b/chromeos/dbus/modem_messaging_client_unittest.cc @@ -0,0 +1,248 @@ +// 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 "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(const dbus::ObjectPath &sms, bool complete)); +}; + +// A mock DeleteCallback. +class MockDeleteCallback { + public: + MOCK_METHOD0(Run, void()); +}; + +// A mock ListCallback. +class MockListCallback { + public: + MOCK_METHOD1(Run, void(const std::vector<dbus::ObjectPath>& 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 ModemMessagingClientTest : public testing::Test { + public: + ModemMessagingClientTest() : 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::kModemManager1MessagingInterface, + modemmanager::kSMSAddedSignal, _, _)) + .WillRepeatedly( + Invoke(this, &ModemMessagingClientTest::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(ModemMessagingClient::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::kModemManager1MessagingInterface, + method_call->GetInterface()); + EXPECT_EQ(modemmanager::kSMSDeleteFunction, method_call->GetMember()); + dbus::ObjectPath sms_path; + dbus::MessageReader reader(method_call); + EXPECT_TRUE(reader.PopObjectPath(&sms_path)); + EXPECT_EQ(expected_sms_path_, sms_path); + 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::kModemManager1MessagingInterface, + 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 List. + void CheckResult(const std::vector<dbus::ObjectPath>& result) { + EXPECT_EQ(result, *expected_result_); + } + + protected: + // The client to be tested. + scoped_ptr<ModemMessagingClient> 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 method. + dbus::ObjectPath expected_sms_path_; + // Response returned by mock methods. + dbus::Response* response_; + // Expected result of List method. + std::vector<dbus::ObjectPath>* 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(ModemMessagingClientTest, SmsReceived) { + // Set expectations. + const dbus::ObjectPath kSmsPath("/SMS/0"); + const bool kComplete = true; + MockSmsReceivedHandler handler; + EXPECT_CALL(handler, Run(kSmsPath, 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::kModemManager1MessagingInterface, + modemmanager::kSMSAddedSignal); + dbus::MessageWriter writer(&signal); + writer.AppendObjectPath(kSmsPath); + 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(ModemMessagingClientTest, Delete) { + // Set expectations. + const dbus::ObjectPath kSmsPath("/SMS/0"); + expected_sms_path_ = kSmsPath; + EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _)) + .WillOnce(Invoke(this, &ModemMessagingClientTest::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), kSmsPath, + base::Bind(&MockDeleteCallback::Run, + base::Unretained(&callback))); + + // Run the message loop. + message_loop_.RunAllPending(); +} + +TEST_F(ModemMessagingClientTest, List) { + // Set expectations. + EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _)) + .WillOnce(Invoke(this, &ModemMessagingClientTest::OnList)); + MockListCallback callback; + EXPECT_CALL(callback, Run(_)) + .WillOnce(Invoke(this, &ModemMessagingClientTest::CheckResult)); + // Create response. + scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); + dbus::ObjectPath path1("/SMS/1"); + dbus::ObjectPath path2("/SMS/2"); + std::vector<dbus::ObjectPath> expected_result; + expected_result.push_back(path1); + expected_result.push_back(path2); + + dbus::MessageWriter writer(response.get()); + writer.AppendArrayOfObjectPaths(expected_result); + response_ = response.get(); + + // Save expected result. + expected_result_ = &expected_result; + // Call List. + 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/sms_client.cc b/chromeos/dbus/sms_client.cc new file mode 100644 index 0000000..d923d8f --- /dev/null +++ b/chromeos/dbus/sms_client.cc @@ -0,0 +1,130 @@ +// 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/sms_client.h" + +#include <map> +#include <utility> + +#include "base/bind.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop.h" +#include "base/stringprintf.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 { + +// SMSClient is used to communicate with the +// org.freedesktop.ModemManager1.SMS service. All methods should be +// called from the origin thread (UI thread) which initializes the +// DBusThreadManager instance. +class SMSClientImpl : public SMSClient { + public: + explicit SMSClientImpl(dbus::Bus* bus) : bus_(bus), weak_ptr_factory_(this) {} + virtual ~SMSClientImpl() {} + + // Calls GetAll method. |callback| is called after the method call succeeds. + virtual void GetAll(const std::string& service_name, + const dbus::ObjectPath& object_path, + const GetAllCallback& callback) OVERRIDE { + dbus::ObjectProxy *proxy = bus_->GetObjectProxy(service_name, object_path); + dbus::MethodCall method_call(dbus::kDBusPropertiesInterface, + dbus::kDBusPropertiesGetAll); + dbus::MessageWriter writer(&method_call); + writer.AppendString(modemmanager::kModemManager1SmsInterface); + proxy->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&SMSClientImpl::OnGetAll, + weak_ptr_factory_.GetWeakPtr(), + callback)); + } + + private: + // Handles responses of GetAll method calls. + void OnGetAll(const GetAllCallback& callback, dbus::Response* response) { + if (!response) { + // Must invoke the callback, even if there is no message. + callback.Run(base::DictionaryValue()); + 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(); + callback.Run(base::DictionaryValue()); + return; + } + callback.Run(*dictionary_value); + } + + dbus::Bus* bus_; + base::WeakPtrFactory<SMSClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SMSClientImpl); +}; + +class SMSClientStubImpl : public SMSClient { + public: + SMSClientStubImpl() : weak_ptr_factory_(this) {} + virtual ~SMSClientStubImpl() {} + + virtual void GetAll(const std::string& service_name, + const dbus::ObjectPath& object_path, + const GetAllCallback& callback) OVERRIDE { + // Ownership passed to callback + base::DictionaryValue *sms = new base::DictionaryValue(); + sms->SetString("Number", "000-000-0000"); + sms->SetString("Text", + "SMSClientStubImpl: Test Message: " + object_path.value()); + sms->SetString("Timestamp", "Fri Jun 8 13:26:04 EDT 2012"); + + // Run callback asynchronously. + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&SMSClientStubImpl::OnGetAll, + weak_ptr_factory_.GetWeakPtr(), + base::Owned(sms), + callback)); + } + + private: + void OnGetAll(base::DictionaryValue *sms, + const GetAllCallback& callback) { + callback.Run(*sms); + } + + base::WeakPtrFactory<SMSClientStubImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SMSClientStubImpl); +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// SMSClient + +SMSClient::SMSClient() {} + +SMSClient::~SMSClient() {} + + +// static +SMSClient* SMSClient::Create(DBusClientImplementationType type, + dbus::Bus* bus) { + if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { + return new SMSClientImpl(bus); + } + DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); + return new SMSClientStubImpl(); +} + +} // namespace chromeos diff --git a/chromeos/dbus/sms_client.h b/chromeos/dbus/sms_client.h new file mode 100644 index 0000000..44006cd --- /dev/null +++ b/chromeos/dbus/sms_client.h @@ -0,0 +1,57 @@ +// 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_SMS_CLIENT_H_ +#define CHROMEOS_DBUS_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; +} + +namespace dbus { +class Bus; +class ObjectPath; +} + +namespace chromeos { + +// SMSMessageClient is used to communicate with the +// org.freedesktop.ModemManager1.SMS service. All methods should be +// called from the origin thread (UI thread) which initializes the +// DBusThreadManager instance. +class CHROMEOS_EXPORT SMSClient { + public: + typedef base::Callback<void(const base::DictionaryValue& sms)> GetAllCallback; + + virtual ~SMSClient(); + + // Factory function, creates a new instance and returns ownership. + // For normal usage, access the singleton via DBusThreadManager::Get(). + static SMSClient* Create(DBusClientImplementationType type, + dbus::Bus* bus); + + // Calls GetAll method. |callback| is called after the method call succeeds. + virtual void GetAll(const std::string& service_name, + const dbus::ObjectPath& object_path, + const GetAllCallback& callback) = 0; + + protected: + // Create() should be used instead. + SMSClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(SMSClient); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_SMS_CLIENT_H_ |