15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_service_client.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/weak_ptr.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/network/network_event_log.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef DBUS_ERROR_UNKNOWN_OBJECT 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The linux_chromeos ASAN builder has an older version of dbus-protocol.h 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// so make sure this is defined. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject" 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Error callback for GetProperties. 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OnGetDictionaryError( 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& method_name, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const dbus::ObjectPath& service_path, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ShillServiceClient::DictionaryValueCallback& callback, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_name, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_message) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string log_string = 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Failed to call org.chromium.shill.Service." + method_name + 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " for: " + service_path.value() + ": " + 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error_name + ": " + error_message; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Suppress ERROR messages for UnknownMethod/Object" since this can 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // happen under normal conditions. See crbug.com/130660 and crbug.com/222210. 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (error_name == DBUS_ERROR_UNKNOWN_METHOD || 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error_name == DBUS_ERROR_UNKNOWN_OBJECT) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << log_string; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << log_string; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue empty_dictionary; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The ShillServiceClient implementation. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ShillServiceClientImpl : public ShillServiceClient { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) explicit ShillServiceClientImpl() 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : bus_(NULL), 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~ShillServiceClientImpl() { 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (HelperMap::iterator iter = helpers_.begin(); 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter != helpers_.end(); ++iter) { 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShillClientHelper* helper = iter->second; 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bus_->RemoveObjectProxy(shill::kFlimflamServiceName, 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) helper->object_proxy()->object_path(), 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&base::DoNothing)); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delete helper; 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddPropertyChangedObserver( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const dbus::ObjectPath& service_path, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShillPropertyChangedObserver* observer) OVERRIDE { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->AddPropertyChangedObserver(observer); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RemovePropertyChangedObserver( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const dbus::ObjectPath& service_path, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShillPropertyChangedObserver* observer) OVERRIDE { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->RemovePropertyChangedObserver(observer); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetProperties(const dbus::ObjectPath& service_path, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DictionaryValueCallback& callback) OVERRIDE { 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kGetPropertiesFunction); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(callback, DBUS_METHOD_CALL_SUCCESS), 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&OnGetDictionaryError, "GetProperties", 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_path, callback)); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetProperty(const dbus::ObjectPath& service_path, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value& value, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kSetPropertyFunction); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendString(name); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShillClientHelper::AppendValueDataAsVariant(&writer, value); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void SetProperties(const dbus::ObjectPath& service_path, 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::DictionaryValue& properties, 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Closure& callback, 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ErrorCallback& error_callback) OVERRIDE { 11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shill::kSetPropertiesFunction); 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus::MessageWriter writer(&method_call); 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ShillClientHelper::AppendServicePropertiesDictionary(&writer, properties); 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback, 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error_callback); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ClearProperty(const dbus::ObjectPath& service_path, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kClearPropertyFunction); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendString(name); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ClearProperties(const dbus::ObjectPath& service_path, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& names, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValueCallback& callback, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shill::kClearPropertiesFunction); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendArrayOfStrings(names); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallListValueMethodWithErrorCallback( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Connect(const dbus::ObjectPath& service_path, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kConnectFunction); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, callback, error_callback); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Disconnect(const dbus::ObjectPath& service_path, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kDisconnectFunction); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Remove(const dbus::ObjectPath& service_path, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kRemoveServiceFunction); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ActivateCellularModem( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const dbus::ObjectPath& service_path, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& carrier, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kActivateCellularModemFunction); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendString(carrier); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void CompleteCellularActivation( 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const dbus::ObjectPath& service_path, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shill::kCompleteCellularActivationFunction); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_callback); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetLoadableProfileEntries( 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const dbus::ObjectPath& service_path, 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DictionaryValueCallback& callback) OVERRIDE { 20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dbus::MethodCall method_call(shill::kFlimflamServiceInterface, 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch shill::kGetLoadableProfileEntriesFunction); 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback( 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &method_call, 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, DBUS_METHOD_CALL_SUCCESS), 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&OnGetDictionaryError, "GetLoadableProfileEntries", 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_path, callback)); 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected: 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual void Init(dbus::Bus* bus) OVERRIDE { 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bus_ = bus; 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, ShillClientHelper*> HelperMap; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the corresponding ShillClientHelper for the profile. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HelperMap::iterator it = helpers_.find(service_path.value()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != helpers_.end()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it->second; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no helper for the profile, create it. 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NET_LOG_DEBUG("AddShillClientHelper", service_path.value()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy* object_proxy = 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bus_->GetObjectProxy(shill::kFlimflamServiceName, service_path); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShillClientHelper* helper = new ShillClientHelper(object_proxy); 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) helper->SetReleasedCallback( 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&ShillServiceClientImpl::NotifyReleased, 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) helper->MonitorPropertyChanged(shill::kFlimflamServiceInterface); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers_.insert(HelperMap::value_type(service_path.value(), helper)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void NotifyReleased(ShillClientHelper* helper) { 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // New Shill Service DBus objects are created relatively frequently, so 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // remove them when they become inactive (no observers and no active method 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // calls). 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dbus::ObjectPath object_path = helper->object_proxy()->object_path(); 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make sure we don't release the proxy used by ShillManagerClient ("/"). 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // This shouldn't ever happen, but might if a bug in the code requests 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // a service with path "/", or a bug in Shill passes "/" as a service path. 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Either way this would cause an invalid memory access in 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ShillManagerClient, see crbug.com/324849. 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (object_path == dbus::ObjectPath(shill::kFlimflamServicePath)) { 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NET_LOG_ERROR("ShillServiceClient service has invalid path", 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shill::kFlimflamServicePath); 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NET_LOG_DEBUG("RemoveShillClientHelper", object_path.value()); 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bus_->RemoveObjectProxy(shill::kFlimflamServiceName, 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) object_path, base::Bind(&base::DoNothing)); 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) helpers_.erase(object_path.value()); 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delete helper; 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::Bus* bus_; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HelperMap helpers_; 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::WeakPtrFactory<ShillServiceClientImpl> weak_ptr_factory_; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillServiceClient::ShillServiceClient() {} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillServiceClient::~ShillServiceClient() {} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ShillServiceClient* ShillServiceClient::Create() { 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return new ShillServiceClientImpl(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 290