| // 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/shill_device_client.h" |
| |
| #include <map> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/macros.h" |
| #include "base/stl_util.h" |
| #include "base/values.h" |
| #include "chromeos/dbus/shill_property_changed_observer.h" |
| #include "dbus/bus.h" |
| #include "dbus/message.h" |
| #include "dbus/object_path.h" |
| #include "dbus/object_proxy.h" |
| #include "dbus/values_util.h" |
| #include "net/base/ip_endpoint.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| namespace chromeos { |
| |
| namespace { |
| |
| // The ShillDeviceClient implementation. |
| class ShillDeviceClientImpl : public ShillDeviceClient { |
| public: |
| ShillDeviceClientImpl() : bus_(NULL) {} |
| |
| ~ShillDeviceClientImpl() override { |
| for (HelperMap::iterator iter = helpers_.begin(); iter != helpers_.end(); |
| ++iter) { |
| // This *should* never happen, yet we're getting crash reports that |
| // seem to imply that it does happen sometimes. Adding CHECKs here |
| // so we can determine more accurately where the problem lies. |
| // See: http://crbug.com/170541 |
| CHECK(iter->second) << "NULL Helper found in helper list."; |
| delete iter->second; |
| } |
| helpers_.clear(); |
| } |
| |
| /////////////////////////////////////// |
| // ShillDeviceClient overrides. |
| void AddPropertyChangedObserver( |
| const dbus::ObjectPath& device_path, |
| ShillPropertyChangedObserver* observer) override { |
| GetHelper(device_path)->AddPropertyChangedObserver(observer); |
| } |
| |
| void RemovePropertyChangedObserver( |
| const dbus::ObjectPath& device_path, |
| ShillPropertyChangedObserver* observer) override { |
| GetHelper(device_path)->RemovePropertyChangedObserver(observer); |
| } |
| |
| void GetProperties(const dbus::ObjectPath& device_path, |
| const DictionaryValueCallback& callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kGetPropertiesFunction); |
| GetHelper(device_path)->CallDictionaryValueMethod(&method_call, callback); |
| } |
| |
| void SetProperty(const dbus::ObjectPath& device_path, |
| const std::string& name, |
| const base::Value& value, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kSetPropertyFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(name); |
| ShillClientHelper::AppendValueDataAsVariant(&writer, value); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void ClearProperty(const dbus::ObjectPath& device_path, |
| const std::string& name, |
| VoidDBusMethodCallback callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kClearPropertyFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(name); |
| GetHelper(device_path)->CallVoidMethod(&method_call, std::move(callback)); |
| } |
| |
| void RequirePin(const dbus::ObjectPath& device_path, |
| const std::string& pin, |
| bool require, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kRequirePinFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(pin); |
| writer.AppendBool(require); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void EnterPin(const dbus::ObjectPath& device_path, |
| const std::string& pin, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kEnterPinFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(pin); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void UnblockPin(const dbus::ObjectPath& device_path, |
| const std::string& puk, |
| const std::string& pin, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kUnblockPinFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(puk); |
| writer.AppendString(pin); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void ChangePin(const dbus::ObjectPath& device_path, |
| const std::string& old_pin, |
| const std::string& new_pin, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kChangePinFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(old_pin); |
| writer.AppendString(new_pin); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void Register(const dbus::ObjectPath& device_path, |
| const std::string& network_id, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kRegisterFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(network_id); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void SetCarrier(const dbus::ObjectPath& device_path, |
| const std::string& carrier, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kSetCarrierFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(carrier); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void Reset(const dbus::ObjectPath& device_path, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kResetFunction); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void PerformTDLSOperation(const dbus::ObjectPath& device_path, |
| const std::string& operation, |
| const std::string& peer, |
| const StringCallback& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kPerformTDLSOperationFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(operation); |
| writer.AppendString(peer); |
| GetHelper(device_path) |
| ->CallStringMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void AddWakeOnPacketConnection(const dbus::ObjectPath& device_path, |
| const net::IPEndPoint& ip_endpoint, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| if (ip_endpoint.address().empty()) { |
| LOG(ERROR) << "AddWakeOnPacketConnection: null address"; |
| return; |
| } |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kAddWakeOnPacketConnectionFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(ip_endpoint.ToStringWithoutPort()); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void AddWakeOnPacketOfTypes(const dbus::ObjectPath& device_path, |
| const std::vector<std::string>& types, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kAddWakeOnPacketOfTypesFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendArrayOfStrings(types); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void RemoveWakeOnPacketConnection( |
| const dbus::ObjectPath& device_path, |
| const net::IPEndPoint& ip_endpoint, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| if (ip_endpoint.address().empty()) { |
| LOG(ERROR) << "RemoveWakeOnPacketConnection: null address"; |
| return; |
| } |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kRemoveWakeOnPacketConnectionFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(ip_endpoint.ToStringWithoutPort()); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void RemoveWakeOnPacketOfTypes(const dbus::ObjectPath& device_path, |
| const std::vector<std::string>& types, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, |
| shill::kRemoveWakeOnPacketOfTypesFunction); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendArrayOfStrings(types); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| void RemoveAllWakeOnPacketConnections( |
| const dbus::ObjectPath& device_path, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) override { |
| dbus::MethodCall method_call( |
| shill::kFlimflamDeviceInterface, |
| shill::kRemoveAllWakeOnPacketConnectionsFunction); |
| GetHelper(device_path) |
| ->CallVoidMethodWithErrorCallback(&method_call, callback, |
| error_callback); |
| } |
| |
| TestInterface* GetTestInterface() override { return NULL; } |
| |
| protected: |
| void Init(dbus::Bus* bus) override { bus_ = bus; } |
| |
| private: |
| typedef std::map<std::string, ShillClientHelper*> HelperMap; |
| |
| // Returns the corresponding ShillClientHelper for the profile. |
| ShillClientHelper* GetHelper(const dbus::ObjectPath& device_path) { |
| HelperMap::iterator it = helpers_.find(device_path.value()); |
| if (it != helpers_.end()) { |
| CHECK(it->second) << "Found a NULL helper in the list."; |
| return it->second; |
| } |
| |
| // There is no helper for the profile, create it. |
| dbus::ObjectProxy* object_proxy = |
| bus_->GetObjectProxy(shill::kFlimflamServiceName, device_path); |
| ShillClientHelper* helper = new ShillClientHelper(object_proxy); |
| CHECK(helper) << "Unable to create Shill client helper."; |
| helper->MonitorPropertyChanged(shill::kFlimflamDeviceInterface); |
| helpers_.insert(HelperMap::value_type(device_path.value(), helper)); |
| return helper; |
| } |
| |
| dbus::Bus* bus_; |
| HelperMap helpers_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ShillDeviceClientImpl); |
| }; |
| |
| } // namespace |
| |
| ShillDeviceClient::ShillDeviceClient() = default; |
| |
| ShillDeviceClient::~ShillDeviceClient() = default; |
| |
| // static |
| ShillDeviceClient* ShillDeviceClient::Create() { |
| return new ShillDeviceClientImpl(); |
| } |
| |
| } // namespace chromeos |