18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/fake_shill_manager_client.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/command_line.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/values.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_device_client.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_profile_client.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_service_client.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/bus.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/message.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/object_path.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/values_util.h"
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Used to compare values for finding entries to erase in a ListValue.
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// (ListValue only implements a const_iterator version of Find).
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct ValueEquals {
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  explicit ValueEquals(const base::Value* first) : first_(first) {}
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool operator()(const base::Value* second) const {
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return first_->Equals(second);
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::Value* first_;
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Appends string entries from |service_list_in| whose entries in ServiceClient
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// have Type |match_type| to either an active list or an inactive list
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// based on the entry's State.
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void AppendServicesForType(
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::ListValue* service_list_in,
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* match_type,
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::vector<std::string>* active_service_list_out,
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::vector<std::string>* inactive_service_list_out) {
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ShillServiceClient::TestInterface* service_client =
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::ListValue::const_iterator iter = service_list_in->begin();
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       iter != service_list_in->end(); ++iter) {
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string service_path;
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!(*iter)->GetAsString(&service_path))
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::DictionaryValue* properties =
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        service_client->GetServiceProperties(service_path);
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!properties) {
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      LOG(ERROR) << "Properties not found for service: " << service_path;
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string type;
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    properties->GetString(shill::kTypeProperty, &type);
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (type != match_type)
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string state;
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    properties->GetString(shill::kStateProperty, &state);
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (state == shill::kStateOnline ||
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        state == shill::kStateAssociation ||
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        state == shill::kStateConfiguration ||
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        state == shill::kStatePortal ||
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        state == shill::kStateReady) {
698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      active_service_list_out->push_back(service_path);
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    } else {
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      inactive_service_list_out->push_back(service_path);
728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillManagerClient::FakeShillManagerClient()
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : weak_ptr_factory_(this) {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillManagerClient::~FakeShillManagerClient() {}
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShillManagerClient overrides.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::Init(dbus::Bus* bus) {}
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddPropertyChangedObserver(
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  observer_list_.AddObserver(observer);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::RemovePropertyChangedObserver(
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::GetProperties(
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const DictionaryValueCallback& callback) {
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, base::Bind(
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          &FakeShillManagerClient::PassStubProperties,
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          callback));
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::GetNetworksForGeolocation(
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const DictionaryValueCallback& callback) {
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, base::Bind(
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          &FakeShillManagerClient::PassStubGeoNetworks,
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          callback));
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeShillManagerClient::SetProperty(const std::string& name,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         const base::Value& value,
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         const base::Closure& callback,
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(name, 0);
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::RequestScan(const std::string& type,
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                         const base::Closure& callback,
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // For Stub purposes, default to a Wifi scan.
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string device_type = shill::kTypeWifi;
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!type.empty())
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    device_type = type;
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ShillDeviceClient::TestInterface* device_client =
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string device_path = device_client->GetDevicePathForType(device_type);
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!device_path.empty()) {
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    device_client->SetDeviceProperty(device_path,
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                     shill::kScanningProperty,
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                     base::FundamentalValue(true));
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const int kScanDurationSeconds = 3;
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int scan_duration_seconds = kScanDurationSeconds;
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      chromeos::switches::kEnableStubInteractive)) {
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scan_duration_seconds = 0;
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&FakeShillManagerClient::ScanCompleted,
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), device_path, callback),
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::TimeDelta::FromSeconds(scan_duration_seconds));
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::EnableTechnology(
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& type,
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::Closure& callback,
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kEnabledTechnologiesProperty, &enabled_list)) {
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(error_callback, "StubError", "Property not found"));
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const int kEnableTechnologyDelaySeconds = 3;
1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, true),
1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::TimeDelta::FromSeconds(kEnableTechnologyDelaySeconds));
1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    SetTechnologyEnabled(type, callback, true);
1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::DisableTechnology(
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& type,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kEnabledTechnologiesProperty, &enabled_list)) {
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(error_callback, "StubError", "Property not found"));
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const int kDisableTechnologyDelaySeconds = 3;
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, false),
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::TimeDelta::FromSeconds(kDisableTechnologyDelaySeconds));
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    SetTechnologyEnabled(type, callback, false);
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeShillManagerClient::ConfigureService(
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue& properties,
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ObjectPathCallback& callback,
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ShillServiceClient::TestInterface* service_client =
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string guid;
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string type;
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!properties.GetString(shill::kGuidProperty, &guid) ||
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !properties.GetString(shill::kTypeProperty, &type)) {
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "ConfigureService requies GUID and Type to be defined";
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // If the properties aren't filled out completely, then just return an empty
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // object path.
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // For the purposes of this stub, we're going to assume that the GUID property
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // is set to the service path because we don't want to re-implement Shill's
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // property matching magic here.
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string service_path = guid;
2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string ipconfig_path;
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Merge the new properties with existing properties, if any.
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::DictionaryValue* existing_properties =
2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      service_client->GetServiceProperties(service_path);
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!existing_properties) {
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Add a new service to the service client stub because none exists, yet.
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // This calls AddManagerService.
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    service_client->AddServiceWithIPConfig(service_path, guid, type,
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           shill::kStateIdle, ipconfig_path,
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           true /* visible */,
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           true /* watch */);
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    existing_properties = service_client->GetServiceProperties(service_path);
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged_properties(
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      existing_properties->DeepCopy());
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  merged_properties->MergeDictionary(&properties);
2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Now set all the properties.
2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::DictionaryValue::Iterator iter(*merged_properties);
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    service_client->SetServiceProperty(service_path, iter.key(), iter.value());
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If the Profile property is set, add it to ProfileClient.
2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string profile_path;
2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  merged_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                   &profile_path);
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!profile_path.empty()) {
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        AddService(profile_path, service_path);
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ConfigureServiceForProfile(
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::DictionaryValue& properties,
2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ObjectPathCallback& callback,
2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ErrorCallback& error_callback) {
2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string profile_property;
2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           &profile_property);
2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(profile_property == profile_path.value());
2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ConfigureService(properties, callback, error_callback);
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::GetService(
2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::DictionaryValue& properties,
2828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ObjectPathCallback& callback,
2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ErrorCallback& error_callback) {
2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
2858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeShillManagerClient::VerifyDestination(
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const VerificationProperties& properties,
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const BooleanCallback& callback,
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::VerifyAndEncryptCredentials(
2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const VerificationProperties& properties,
2978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& service_path,
2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const StringCallback& callback,
2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ErrorCallback& error_callback) {
3008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, base::Bind(callback, "encrypted_credentials"));
3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::VerifyAndEncryptData(
3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const VerificationProperties& properties,
3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& data,
3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const StringCallback& callback,
3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ErrorCallback& error_callback) {
3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                   base::Bind(callback, "encrypted_data"));
3118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ConnectToBestServices(
3148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::Closure& callback,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() {
3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return this;
3208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShillManagerClient::TestInterface overrides.
3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddDevice(const std::string& device_path) {
3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kDevicesProperty)->AppendIfNotPresent(
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Value::CreateStringValue(device_path))) {
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::RemoveDevice(const std::string& device_path) {
3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::StringValue device_path_value(device_path);
3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kDevicesProperty)->Remove(
3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      device_path_value, NULL)) {
3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ClearDevices() {
3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kDevicesProperty)->Clear();
3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddTechnology(const std::string& type,
3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           bool enabled) {
3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kAvailableTechnologiesProperty)->
3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        shill::kAvailableTechnologiesProperty, 0);
3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (enabled &&
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetListProperty(shill::kEnabledTechnologiesProperty)->
3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        shill::kEnabledTechnologiesProperty, 0);
3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::RemoveTechnology(const std::string& type) {
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::StringValue type_value(type);
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove(
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      type_value, NULL)) {
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        shill::kAvailableTechnologiesProperty, 0);
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kEnabledTechnologiesProperty)->Remove(
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      type_value, NULL)) {
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        shill::kEnabledTechnologiesProperty, 0);
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::SetTechnologyInitializing(const std::string& type,
3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                       bool initializing) {
3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (initializing) {
3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->
3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            base::StringValue(type), NULL)) {
3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ClearProperties() {
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_properties_.Clear();
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddManagerService(const std::string& service_path,
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               bool add_to_visible_list,
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               bool add_to_watch_list) {
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Always add to ServiceCompleteListProperty.
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceCompleteListProperty)->AppendIfNotPresent(
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Value::CreateStringValue(service_path));
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If visible, add to Services and notify if new.
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (add_to_visible_list &&
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetListProperty(shill::kServicesProperty)->AppendIfNotPresent(
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Value::CreateStringValue(service_path))) {
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (add_to_watch_list)
4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    AddServiceToWatchList(service_path);
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::RemoveManagerService(
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& service_path) {
4128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::StringValue service_path_value(service_path);
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kServicesProperty)->Remove(
4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      service_path_value, NULL)) {
4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceCompleteListProperty)->Remove(
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      service_path_value, NULL);
4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(shill::kServiceWatchListProperty)->Remove(
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      service_path_value, NULL)) {
4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        shill::kServiceWatchListProperty, 0);
4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ClearManagerServices() {
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServicesProperty)->Clear();
4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceCompleteListProperty)->Clear();
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceWatchListProperty)->Clear();
4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::SortManagerServices() {
4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static const char* ordered_types[] = {
4368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    shill::kTypeEthernet,
4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    shill::kTypeWifi,
4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    shill::kTypeCellular,
4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    shill::kTypeWimax,
4408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    shill::kTypeVPN
4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  };
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* service_list = GetListProperty(shill::kServicesProperty);
4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!service_list || service_list->empty())
4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<std::string> active_services;
4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<std::string> inactive_services;
4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(ordered_types); ++i) {
4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    AppendServicesForType(service_list, ordered_types[i],
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                          &active_services, &inactive_services);
4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  service_list->Clear();
4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < active_services.size(); ++i)
4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    service_list->AppendString(active_services[i]);
4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < inactive_services.size(); ++i)
4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    service_list->AppendString(inactive_services[i]);
4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddGeoNetwork(
4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& technology,
4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::DictionaryValue& network) {
4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* list_value = NULL;
4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_geo_networks_.GetListWithoutPathExpansion(
4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      technology, &list_value)) {
4668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    list_value = new base::ListValue;
4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  list_value->Append(network.DeepCopy());
4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const char* key = shill::kProfilesProperty;
4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (GetListProperty(key)->AppendIfNotPresent(
4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          new base::StringValue(profile_path))) {
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    CallNotifyObserversPropertyChanged(key, 0);
4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::AddServiceToWatchList(
4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& service_path) {
4828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Remove and insert the service, moving it to the front of the watch list.
4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceWatchListProperty)->Remove(
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::StringValue(service_path), NULL);
4858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetListProperty(shill::kServiceWatchListProperty)->Insert(
4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      0, base::Value::CreateStringValue(service_path));
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kServiceWatchListProperty, 0);
4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::PassStubProperties(
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> stub_properties(
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      stub_properties_.DeepCopy());
4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Remove disabled services from the list.
4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kServicesProperty,
4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetEnabledServiceList(shill::kServicesProperty));
4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kServiceWatchListProperty,
5018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetEnabledServiceList(shill::kServiceWatchListProperty));
5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
5038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::PassStubGeoNetworks(
5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
5088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& property,
5128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int delay_ms) {
5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Avoid unnecessary delayed task if we have no observers (e.g. during
5148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // initial setup).
5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!observer_list_.might_have_observers())
5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    delay_ms = 0;
5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged,
5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 property),
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 base::TimeDelta::FromMilliseconds(delay_ms));
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::NotifyObserversPropertyChanged(
5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& property) {
5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (property == shill::kServicesProperty ||
5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      property == shill::kServiceWatchListProperty) {
5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                      observer_list_,
5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                      OnPropertyChanged(property, *(services.get())));
5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::Value* value = NULL;
5408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Notify for unknown property: " << property;
5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    observer_list_,
5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    OnPropertyChanged(property, *value));
5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::ListValue* FakeShillManagerClient::GetListProperty(
5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& property) {
5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* list_property = NULL;
5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      property, &list_property)) {
5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    list_property = new base::ListValue;
5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    stub_properties_.SetWithoutPathExpansion(property, list_property);
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return list_property;
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool FakeShillManagerClient::TechnologyEnabled(const std::string& type) const {
5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (type == shill::kTypeVPN)
5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;  // VPN is always "enabled" since there is no associated device
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool enabled = false;
5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::ListValue* technologies;
5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(
5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          shill::kEnabledTechnologiesProperty, &technologies)) {
5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::StringValue type_value(type);
5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (technologies->Find(type_value) != technologies->end())
5698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      enabled = true;
5708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return enabled;
5728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::SetTechnologyEnabled(
5758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& type,
5768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::Closure& callback,
5778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool enabled) {
5788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
5798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_properties_.GetListWithoutPathExpansion(
5808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kEnabledTechnologiesProperty, &enabled_list);
5818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(enabled_list);
5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (enabled)
5838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    enabled_list->AppendIfNotPresent(new base::StringValue(type));
5848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  else
5858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    enabled_list->Remove(base::StringValue(type), NULL);
5868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(
5878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shill::kEnabledTechnologiesProperty, 0 /* already delayed */);
5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
5898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // May affect available services
5908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
5928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::ListValue* FakeShillManagerClient::GetEnabledServiceList(
5958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& property) const {
5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::ListValue* new_service_list = new base::ListValue;
5978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::ListValue* service_list;
5988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ShillServiceClient::TestInterface* service_client =
6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
6018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (base::ListValue::const_iterator iter = service_list->begin();
6028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)         iter != service_list->end(); ++iter) {
6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string service_path;
6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (!(*iter)->GetAsString(&service_path))
6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const base::DictionaryValue* properties =
6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          service_client->GetServiceProperties(service_path);
6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (!properties) {
6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        LOG(ERROR) << "Properties not found for service: " << service_path;
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string name;
6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      properties->GetString(shill::kNameProperty, &name);
6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string type;
6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      properties->GetString(shill::kTypeProperty, &type);
6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (TechnologyEnabled(type))
6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new_service_list->Append((*iter)->DeepCopy());
6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return new_service_list;
6218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillManagerClient::ScanCompleted(const std::string& device_path,
6248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                           const base::Closure& callback) {
6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!device_path.empty()) {
6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        SetDeviceProperty(device_path,
6288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                          shill::kScanningProperty,
6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                          base::FundamentalValue(false));
6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
6328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
6338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
6348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace chromeos
637