1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
// 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/command_line.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 "chromeos/chromeos_switches.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.
base::DictionaryValue empty_dictionary;
callback.Run(empty_dictionary);
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();
base::DictionaryValue empty_dictionary;
callback.Run(empty_dictionary);
return;
}
callback.Run(*dictionary_value);
}
dbus::Bus* bus_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
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 {
if (!CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kSmsTestMessages))
return;
// 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.
if (callback.is_null())
return;
base::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
|