12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_profile_client_stub.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind_helpers.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/dbus/shill_manager_client.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/shill_service_client.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_path.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/values_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)struct ShillProfileClientStub::ProfileProperties { 25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::DictionaryValue entries; 26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::DictionaryValue properties; 27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}; 28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PassDictionary( 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ShillProfileClient::DictionaryValueCallbackWithoutStatus& callback, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* dictionary) { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(*dictionary); 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static 403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ShillProfileClientStub::kSharedProfilePath[] = "/profile/default"; 413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ShillProfileClientStub::ShillProfileClientStub() { 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) AddProfile(kSharedProfilePath, std::string()); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillProfileClientStub::~ShillProfileClientStub() { 47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) STLDeleteValues(&profiles_); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillProfileClientStub::AddPropertyChangedObserver( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const dbus::ObjectPath& profile_path, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShillPropertyChangedObserver* observer) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillProfileClientStub::RemovePropertyChangedObserver( 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const dbus::ObjectPath& profile_path, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShillPropertyChangedObserver* observer) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillProfileClientStub::GetProperties( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const dbus::ObjectPath& profile_path, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DictionaryValueCallbackWithoutStatus& callback, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileProperties* profile = GetProfile(profile_path, error_callback); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!profile) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<base::DictionaryValue> properties(profile->properties.DeepCopy()); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* entry_paths = new base::ListValue; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) properties->SetWithoutPathExpansion(flimflam::kEntriesProperty, entry_paths); 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (base::DictionaryValue::Iterator it(profile->entries); !it.IsAtEnd(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it.Advance()) { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_paths->AppendString(it.key()); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->PostTask( 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PassDictionary, callback, base::Owned(properties.release()))); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillProfileClientStub::GetEntry( 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const dbus::ObjectPath& profile_path, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& entry_path, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DictionaryValueCallbackWithoutStatus& callback, 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileProperties* profile = GetProfile(profile_path, error_callback); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!profile) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* entry = NULL; 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profile->entries.GetDictionaryWithoutPathExpansion(entry_path, &entry); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run("Error.InvalidProfileEntry", "Invalid profile entry"); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->PostTask( 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PassDictionary, callback, base::Owned(entry->DeepCopy()))); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillProfileClientStub::DeleteEntry(const dbus::ObjectPath& profile_path, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& entry_path, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileProperties* profile = GetProfile(profile_path, error_callback); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!profile) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!profile->entries.RemoveWithoutPathExpansion(entry_path, NULL)) { 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error_callback.Run("Error.InvalidProfileEntry", entry_path); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringValue profile_path_value(""); 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()-> 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetServiceProperty(entry_path, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flimflam::kProfileProperty, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_path_value); 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, callback); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ShillProfileClient::TestInterface* ShillProfileClientStub::GetTestInterface() { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return this; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShillProfileClientStub::AddProfile(const std::string& profile_path, 129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& userhash) { 130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (GetProfile(dbus::ObjectPath(profile_path), ErrorCallback())) 131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileProperties* profile = new ProfileProperties; 134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profile->properties.SetStringWithoutPathExpansion(shill::kUserHashProperty, 135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) userhash); 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profiles_[profile_path] = profile; 137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> 138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) AddProfile(profile_path); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillProfileClientStub::AddEntry(const std::string& profile_path, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& entry_path, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& properties) { 144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileProperties* profile = GetProfile(dbus::ObjectPath(profile_path), 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ErrorCallback()); 146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(profile); 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profile->entries.SetWithoutPathExpansion(entry_path, 148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) properties.DeepCopy()); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddManagerService(entry_path, false /* visible */, false /* watch */); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ShillProfileClientStub::AddService(const std::string& profile_path, 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& service_path) { 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProfileProperties* profile = GetProfile(dbus::ObjectPath(profile_path), 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ErrorCallback()); 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!profile) { 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "No matching profile: " << profile_path; 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShillServiceClient::TestInterface* service_test = 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::DictionaryValue* service_properties = 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) service_test->GetServiceProperties(service_path); 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!service_properties) { 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "No matching service: " << service_path; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string service_profile_path; 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_properties->GetStringWithoutPathExpansion(flimflam::kProfileProperty, 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &service_profile_path); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!service_profile_path.empty() && service_profile_path != profile_path) { 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "Service has non matching profile path: " 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << service_profile_path; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringValue profile_path_value(profile_path); 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_test->SetServiceProperty(service_path, 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flimflam::kProfileProperty, 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_path_value); 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile->entries.SetWithoutPathExpansion(service_path, 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_properties->DeepCopy()); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ShillProfileClientStub::GetProfilePaths( 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<std::string>* profiles) { 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ProfileMap::iterator iter = profiles_.begin(); 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch iter != profiles_.end(); ++iter) { 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profiles->push_back(iter->first); 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)ShillProfileClientStub::ProfileProperties* ShillProfileClientStub::GetProfile( 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& profile_path, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) { 199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ProfileMap::const_iterator found = profiles_.find(profile_path.value()); 200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (found == profiles_.end()) { 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!error_callback.is_null()) 202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) error_callback.Run("Error.InvalidProfile", "Invalid profile"); 203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return NULL; 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return found->second; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 210