Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / chromeos / dbus / shill_third_party_vpn_driver_client.cc
bloba1a761c52b8bd528216a07ecb55bc738fce9c1e9
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h"
7 #include "base/bind.h"
8 #include "base/stl_util.h"
9 #include "chromeos/dbus/shill_third_party_vpn_observer.h"
10 #include "dbus/bus.h"
11 #include "dbus/message.h"
12 #include "dbus/object_proxy.h"
13 #include "third_party/cros_system_api/dbus/service_constants.h"
15 namespace chromeos {
17 namespace {
19 const char* kSetParametersKeyList[] = {
20 shill::kAddressParameterThirdPartyVpn,
21 shill::kBroadcastAddressParameterThirdPartyVpn,
22 shill::kExclusionListParameterThirdPartyVpn,
23 shill::kInclusionListParameterThirdPartyVpn,
24 shill::kSubnetPrefixParameterThirdPartyVpn,
25 shill::kMtuParameterThirdPartyVpn,
26 shill::kDomainSearchParameterThirdPartyVpn,
27 shill::kDnsServersParameterThirdPartyVpn};
29 // The ShillThirdPartyVpnDriverClient implementation.
30 class ShillThirdPartyVpnDriverClientImpl
31 : public ShillThirdPartyVpnDriverClient {
32 public:
33 ShillThirdPartyVpnDriverClientImpl();
34 ~ShillThirdPartyVpnDriverClientImpl() override;
36 // ShillThirdPartyVpnDriverClient overrides
37 void AddShillThirdPartyVpnObserver(
38 const std::string& object_path_value,
39 ShillThirdPartyVpnObserver* observer) override;
41 void RemoveShillThirdPartyVpnObserver(
42 const std::string& object_path_value) override;
44 void SetParameters(
45 const std::string& object_path_value,
46 const base::DictionaryValue& parameters,
47 const base::Closure& callback,
48 const ShillClientHelper::ErrorCallback& error_callback) override;
50 void UpdateConnectionState(
51 const std::string& object_path_value,
52 const uint32_t connection_state,
53 const base::Closure& callback,
54 const ShillClientHelper::ErrorCallback& error_callback) override;
56 void SendPacket(
57 const std::string& object_path_value,
58 const std::vector<char>& ip_packet,
59 const base::Closure& callback,
60 const ShillClientHelper::ErrorCallback& error_callback) override;
62 protected:
63 void Init(dbus::Bus* bus) override { bus_ = bus; }
65 ShillThirdPartyVpnDriverClient::TestInterface* GetTestInterface() override {
66 return nullptr;
69 private:
70 class HelperInfo {
71 public:
72 explicit HelperInfo(dbus::ObjectProxy* object_proxy);
74 ShillClientHelper* helper() { return &helper_; }
75 ShillThirdPartyVpnObserver* observer() { return observer_; }
77 void set_observer(ShillThirdPartyVpnObserver* observer) {
78 observer_ = observer;
81 base::WeakPtr<HelperInfo> GetWeakPtr() {
82 return weak_ptr_factory_.GetWeakPtr();
85 private:
86 ShillClientHelper helper_;
87 ShillThirdPartyVpnObserver* observer_;
89 base::WeakPtrFactory<HelperInfo> weak_ptr_factory_;
91 using HelperMap = std::map<std::string, HelperInfo*>;
93 static void OnPacketReceived(base::WeakPtr<HelperInfo> helper_info,
94 dbus::Signal* signal);
95 static void OnPlatformMessage(base::WeakPtr<HelperInfo> helper_info,
96 dbus::Signal* signal);
97 static void OnSignalConnected(const std::string& interface,
98 const std::string& signal,
99 bool success);
101 // Returns or creates the corresponding ShillClientHelper for the
102 // |object_path_value|.
103 ShillClientHelper* GetHelper(const std::string& object_path_value);
105 // Returns or creates the corresponding HelperInfo for the
106 // |object_path_value|.
107 HelperInfo* GetHelperInfo(const std::string& object_path_value);
109 // Returns the corresponding HelperInfo for the |object_path| if exists,
110 // nullptr if not.
111 HelperInfo* FindHelperInfo(const dbus::ObjectPath& object_path);
113 // Deletes the helper object corresponding to |object_path|.
114 void DeleteHelper(const dbus::ObjectPath& object_path);
116 dbus::Bus* bus_;
117 HelperMap helpers_;
118 std::set<std::string> valid_keys_;
120 DISALLOW_COPY_AND_ASSIGN(ShillThirdPartyVpnDriverClientImpl);
123 ShillThirdPartyVpnDriverClientImpl::HelperInfo::HelperInfo(
124 dbus::ObjectProxy* object_proxy)
125 : helper_(object_proxy), observer_(nullptr), weak_ptr_factory_(this) {
128 ShillThirdPartyVpnDriverClientImpl::ShillThirdPartyVpnDriverClientImpl()
129 : bus_(nullptr) {
130 for (uint32_t i = 0; i < arraysize(kSetParametersKeyList); ++i) {
131 valid_keys_.insert(kSetParametersKeyList[i]);
135 ShillThirdPartyVpnDriverClientImpl::~ShillThirdPartyVpnDriverClientImpl() {
136 for (auto& iter : helpers_) {
137 HelperInfo* helper_info = iter.second;
138 bus_->RemoveObjectProxy(
139 shill::kFlimflamServiceName,
140 helper_info->helper()->object_proxy()->object_path(),
141 base::Bind(&base::DoNothing));
142 delete helper_info;
146 void ShillThirdPartyVpnDriverClientImpl::AddShillThirdPartyVpnObserver(
147 const std::string& object_path_value,
148 ShillThirdPartyVpnObserver* observer) {
149 HelperInfo* helper_info = GetHelperInfo(object_path_value);
150 if (helper_info->observer()) {
151 LOG(ERROR) << "Observer exists for " << object_path_value;
152 return;
155 // TODO(kaliamoorthi): Remove the const_cast.
156 helper_info->set_observer(observer);
157 dbus::ObjectProxy* proxy =
158 const_cast<dbus::ObjectProxy*>(helper_info->helper()->object_proxy());
160 proxy->ConnectToSignal(
161 shill::kFlimflamThirdPartyVpnInterface, shill::kOnPlatformMessageFunction,
162 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage,
163 helper_info->GetWeakPtr()),
164 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected));
166 proxy->ConnectToSignal(
167 shill::kFlimflamThirdPartyVpnInterface, shill::kOnPacketReceivedFunction,
168 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPacketReceived,
169 helper_info->GetWeakPtr()),
170 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected));
173 void ShillThirdPartyVpnDriverClientImpl::RemoveShillThirdPartyVpnObserver(
174 const std::string& object_path_value) {
175 HelperInfo* helper_info = FindHelperInfo(dbus::ObjectPath(object_path_value));
176 if (!helper_info) {
177 LOG(ERROR) << "Unknown object_path_value " << object_path_value;
178 return;
181 CHECK(helper_info->observer());
182 helper_info->set_observer(nullptr);
183 DeleteHelper(dbus::ObjectPath(object_path_value));
186 void ShillThirdPartyVpnDriverClientImpl::DeleteHelper(
187 const dbus::ObjectPath& object_path) {
188 HelperInfo* helper_info = FindHelperInfo(dbus::ObjectPath(object_path));
189 if (!helper_info) {
190 LOG(ERROR) << "Unknown object_path " << object_path.value();
191 return;
194 bus_->RemoveObjectProxy(shill::kFlimflamServiceName, object_path,
195 base::Bind(&base::DoNothing));
196 helpers_.erase(helpers_.find(object_path.value()));
197 delete helper_info;
200 void ShillThirdPartyVpnDriverClientImpl::SetParameters(
201 const std::string& object_path_value,
202 const base::DictionaryValue& parameters,
203 const base::Closure& callback,
204 const ShillClientHelper::ErrorCallback& error_callback) {
205 dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface,
206 shill::kSetParametersFunction);
207 dbus::MessageWriter writer(&method_call);
208 dbus::MessageWriter array_writer(nullptr);
209 writer.OpenArray("{ss}", &array_writer);
210 for (base::DictionaryValue::Iterator it(parameters); !it.IsAtEnd();
211 it.Advance()) {
212 if (valid_keys_.find(it.key()) == valid_keys_.end()) {
213 LOG(WARNING) << "Unknown key " << it.key();
214 continue;
216 std::string value;
217 if (!it.value().GetAsString(&value)) {
218 LOG(WARNING) << "Non string value " << it.value();
219 continue;
221 dbus::MessageWriter entry_writer(nullptr);
222 array_writer.OpenDictEntry(&entry_writer);
223 entry_writer.AppendString(it.key());
224 entry_writer.AppendString(value);
225 array_writer.CloseContainer(&entry_writer);
227 writer.CloseContainer(&array_writer);
228 GetHelper(object_path_value)
229 ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback);
232 void ShillThirdPartyVpnDriverClientImpl::UpdateConnectionState(
233 const std::string& object_path_value,
234 const uint32_t connection_state,
235 const base::Closure& callback,
236 const ShillClientHelper::ErrorCallback& error_callback) {
237 dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface,
238 shill::kUpdateConnectionStateFunction);
239 dbus::MessageWriter writer(&method_call);
240 writer.AppendUint32(connection_state);
241 GetHelper(object_path_value)
242 ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback);
245 void ShillThirdPartyVpnDriverClientImpl::SendPacket(
246 const std::string& object_path_value,
247 const std::vector<char>& ip_packet,
248 const base::Closure& callback,
249 const ShillClientHelper::ErrorCallback& error_callback) {
250 dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface,
251 shill::kSendPacketFunction);
252 dbus::MessageWriter writer(&method_call);
253 static_assert(sizeof(uint8_t) == sizeof(char),
254 "Can't reinterpret ip_packet if char is not 8 bit large.");
255 writer.AppendArrayOfBytes(
256 reinterpret_cast<const uint8_t*>(vector_as_array(&ip_packet)),
257 ip_packet.size());
258 GetHelper(object_path_value)
259 ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback);
262 // static
263 void ShillThirdPartyVpnDriverClientImpl::OnPacketReceived(
264 base::WeakPtr<HelperInfo> helper_info,
265 dbus::Signal* signal) {
266 if (!helper_info || !helper_info->observer())
267 return;
269 dbus::MessageReader reader(signal);
270 const uint8_t* data = nullptr;
271 size_t length = 0;
272 if (reader.PopArrayOfBytes(&data, &length)) {
273 helper_info->observer()->OnPacketReceived(
274 std::vector<char>(data, data + length));
278 // static
279 void ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage(
280 base::WeakPtr<HelperInfo> helper_info,
281 dbus::Signal* signal) {
282 if (!helper_info || !helper_info->observer())
283 return;
285 dbus::MessageReader reader(signal);
286 uint32_t platform_message = 0;
287 if (reader.PopUint32(&platform_message))
288 helper_info->observer()->OnPlatformMessage(platform_message);
291 // static
292 void ShillThirdPartyVpnDriverClientImpl::OnSignalConnected(
293 const std::string& interface,
294 const std::string& signal,
295 bool success) {
296 LOG_IF(ERROR, !success) << "Connect to " << interface << " " << signal
297 << " failed.";
300 ShillClientHelper* ShillThirdPartyVpnDriverClientImpl::GetHelper(
301 const std::string& object_path_value) {
302 return GetHelperInfo(object_path_value)->helper();
305 ShillThirdPartyVpnDriverClientImpl::HelperInfo*
306 ShillThirdPartyVpnDriverClientImpl::FindHelperInfo(
307 const dbus::ObjectPath& object_path) {
308 HelperMap::iterator it = helpers_.find(object_path.value());
309 return (it != helpers_.end()) ? it->second : nullptr;
312 ShillThirdPartyVpnDriverClientImpl::HelperInfo*
313 ShillThirdPartyVpnDriverClientImpl::GetHelperInfo(
314 const std::string& object_path_value) {
315 dbus::ObjectPath object_path(object_path_value);
316 HelperInfo* helper_info = FindHelperInfo(object_path);
317 if (helper_info)
318 return helper_info;
320 // There is no helper for the profile, create it.
321 dbus::ObjectProxy* object_proxy =
322 bus_->GetObjectProxy(shill::kFlimflamServiceName, object_path);
323 helper_info = new HelperInfo(object_proxy);
324 helpers_[object_path_value] = helper_info;
325 return helper_info;
328 } // namespace
330 ShillThirdPartyVpnDriverClient::ShillThirdPartyVpnDriverClient() {
333 ShillThirdPartyVpnDriverClient::~ShillThirdPartyVpnDriverClient() {
336 // static
337 ShillThirdPartyVpnDriverClient* ShillThirdPartyVpnDriverClient::Create() {
338 return new ShillThirdPartyVpnDriverClientImpl();
341 } // namespace chromeos