18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 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)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/fake_shill_profile_client.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)
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct FakeShillProfileClient::ProfileProperties {
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::DictionaryValue entries;  // Dictionary of Service Dictionaries
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::DictionaryValue properties;  // Dictionary of Profile 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)
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillProfileClient::FakeShillProfileClient() {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillProfileClient::~FakeShillProfileClient() {
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  STLDeleteValues(&profiles_);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::Init(dbus::Bus* bus) {
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::AddPropertyChangedObserver(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::RemovePropertyChangedObserver(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::GetProperties(
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallbackWithoutStatus& callback,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileProperties* profile = GetProfile(profile_path, error_callback);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!profile)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> properties(profile->properties.DeepCopy());
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ListValue* entry_paths = new base::ListValue;
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  properties->SetWithoutPathExpansion(shill::kEntriesProperty, entry_paths);
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  for (base::DictionaryValue::Iterator it(profile->entries); !it.IsAtEnd();
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       it.Advance()) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    entry_paths->AppendString(it.key());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&PassDictionary, callback, base::Owned(properties.release())));
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::GetEntry(
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& entry_path,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallbackWithoutStatus& callback,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileProperties* profile = GetProfile(profile_path, error_callback);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!profile)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue* entry = NULL;
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  profile->entries.GetDictionaryWithoutPathExpansion(entry_path, &entry);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!entry) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_callback.Run("Error.InvalidProfileEntry", "Invalid profile entry");
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&PassDictionary, callback, base::Owned(entry->DeepCopy())));
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::DeleteEntry(const dbus::ObjectPath& profile_path,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const std::string& entry_path,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Closure& callback,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileProperties* profile = GetProfile(profile_path, error_callback);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!profile)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!profile->entries.RemoveWithoutPathExpansion(entry_path, NULL)) {
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    error_callback.Run("Error.InvalidProfileEntry", entry_path);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::StringValue profile_path_value("");
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      SetServiceProperty(entry_path,
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         shill::kProfileProperty,
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         profile_path_value);
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShillProfileClient::TestInterface* FakeShillProfileClient::GetTestInterface() {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return this;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::AddProfile(const std::string& profile_path,
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                        const std::string& userhash) {
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (GetProfile(dbus::ObjectPath(profile_path), ErrorCallback()))
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileProperties* profile = new ProfileProperties;
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  profile->properties.SetStringWithoutPathExpansion(shill::kUserHashProperty,
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                    userhash);
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  profiles_[profile_path] = profile;
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      AddProfile(profile_path);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::AddEntry(const std::string& profile_path,
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const std::string& entry_path,
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const base::DictionaryValue& properties) {
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileProperties* profile = GetProfile(dbus::ObjectPath(profile_path),
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                          ErrorCallback());
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(profile);
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  profile->entries.SetWithoutPathExpansion(entry_path, properties.DeepCopy());
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
1486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      AddManagerService(entry_path, true);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool FakeShillProfileClient::AddService(const std::string& profile_path,
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        const std::string& service_path) {
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ProfileProperties* profile = GetProfile(dbus::ObjectPath(profile_path),
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          ErrorCallback());
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile) {
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LOG(ERROR) << "AddService: No matching profile: " << profile_path
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)               << " for: " << service_path;
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (profile->entries.HasKey(service_path))
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return AddOrUpdateServiceImpl(profile_path, service_path, profile);
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool FakeShillProfileClient::UpdateService(const std::string& profile_path,
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           const std::string& service_path) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ProfileProperties* profile = GetProfile(dbus::ObjectPath(profile_path),
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          ErrorCallback());
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!profile) {
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LOG(ERROR) << "UpdateService: No matching profile: " << profile_path
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)               << " for: " << service_path;
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!profile->entries.HasKey(service_path)) {
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(ERROR) << "UpdateService: Profile: " << profile_path
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               << " does not contain Service: " << service_path;
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return AddOrUpdateServiceImpl(profile_path, service_path, profile);
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool FakeShillProfileClient::AddOrUpdateServiceImpl(
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& profile_path,
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& service_path,
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ProfileProperties* profile) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShillServiceClient::TestInterface* service_test =
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::DictionaryValue* service_properties =
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      service_test->GetServiceProperties(service_path);
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!service_properties) {
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LOG(ERROR) << "No matching service: " << service_path;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string service_profile_path;
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  service_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                    &service_profile_path);
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (service_profile_path.empty()) {
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::StringValue profile_path_value(profile_path);
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    service_test->SetServiceProperty(service_path,
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     shill::kProfileProperty,
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     profile_path_value);
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (service_profile_path != profile_path) {
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LOG(ERROR) << "Service has non matching profile path: "
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               << service_profile_path;
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  profile->entries.SetWithoutPathExpansion(service_path,
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           service_properties->DeepCopy());
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillProfileClient::GetProfilePaths(
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<std::string>* profiles) {
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (ProfileMap::iterator iter = profiles_.begin();
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       iter != profiles_.end(); ++iter) {
217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    profiles->push_back(iter->first);
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool FakeShillProfileClient::GetService(const std::string& service_path,
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        std::string* profile_path,
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        base::DictionaryValue* properties) {
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  properties->Clear();
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ProfileMap::const_iterator iter = profiles_.begin();
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       iter != profiles_.end(); ++iter) {
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ProfileProperties* profile = iter->second;
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::DictionaryValue* entry;
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!profile->entries.GetDictionaryWithoutPathExpansion(
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            service_path, &entry)) {
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *profile_path = iter->first;
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    properties->MergeDictionary(entry);
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeShillProfileClient::ClearProfiles() {
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  STLDeleteValues(&profiles_);
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillProfileClient::ProfileProperties* FakeShillProfileClient::GetProfile(
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProfileMap::const_iterator found = profiles_.find(profile_path.value());
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (found == profiles_.end()) {
249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!error_callback.is_null())
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      error_callback.Run("Error.InvalidProfile", "Invalid profile");
251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return NULL;
252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return found->second;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
258