summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbenchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 08:57:52 +0000
committerbenchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 08:57:52 +0000
commit88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086 (patch)
treec1d0425225fba7fa353b2d71e35f0cd6709f7280
parent7a81ea6ea50832e9f1fff8bc575ef5ce0b915c93 (diff)
downloadchromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.zip
chromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.tar.gz
chromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.tar.bz2
Support the ModemManager1 interfaces for SMS messages
Add dbus support the org.freedesktop.ModemManager1.SMS and org.freedesktop.ModemManager1.Modem.Messaging interfaces. This CL is authored by Jason Glasgow <jglasgow@chromium.org> and reviewed on https://chromiumcodereview.appspot.com/10533006 BUG=chromium-os:28421 TEST=chromeos_unittests Review URL: https://chromiumcodereview.appspot.com/10545133 Patch from Jason Glasgow <jglasgow@chromium.org>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141634 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chromeos/chromeos.gyp9
-rw-r--r--chromeos/dbus/dbus_thread_manager.cc22
-rw-r--r--chromeos/dbus/dbus_thread_manager.h12
-rw-r--r--chromeos/dbus/flimflam_device_client.cc17
-rw-r--r--chromeos/dbus/flimflam_manager_client.cc4
-rw-r--r--chromeos/dbus/gsm_sms_client.cc6
-rw-r--r--chromeos/dbus/gsm_sms_client.h6
-rw-r--r--chromeos/dbus/gsm_sms_client_unittest.cc2
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.cc8
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.h12
-rw-r--r--chromeos/dbus/mock_gsm_sms_client.h2
-rw-r--r--chromeos/dbus/mock_modem_messaging_client.cc13
-rw-r--r--chromeos/dbus/mock_modem_messaging_client.h40
-rw-r--r--chromeos/dbus/mock_sms_client.cc13
-rw-r--r--chromeos/dbus/mock_sms_client.h29
-rw-r--r--chromeos/dbus/modem_messaging_client.cc278
-rw-r--r--chromeos/dbus/modem_messaging_client.h73
-rw-r--r--chromeos/dbus/modem_messaging_client_unittest.cc248
-rw-r--r--chromeos/dbus/sms_client.cc130
-rw-r--r--chromeos/dbus/sms_client.h57
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_