shill_manager_client_stub.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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_manager_client_stub.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/chromeos/chromeos_version.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/message_loop.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/shill_device_client.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/shill_profile_client.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_service_client.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_path.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_proxy.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/values_util.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to compare values for finding entries to erase in a ListValue.
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (ListValue only implements a const_iterator version of Find).
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ValueEquals {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit ValueEquals(const Value* first) : first_(first) {}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool operator()(const Value* second) const {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return first_->Equals(second);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Value* first_;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClientStub::ShillManagerClientStub()
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles): weak_ptr_factory_(this) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetDefaultProperties();
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClientStub::~ShillManagerClientStub() {}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShillManagerClient overrides.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddPropertyChangedObserver(
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.AddObserver(observer);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemovePropertyChangedObserver(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetProperties(
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &ShillManagerClientStub::PassStubProperties,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* ShillManagerClientStub::CallGetPropertiesAndBlock() {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return stub_properties_.DeepCopy();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetNetworksForGeolocation(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &ShillManagerClientStub::PassStubGeoNetworks,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::SetProperty(const std::string& name,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Value& value,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Closure& callback,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(FROM_HERE, callback);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RequestScan(const std::string& type,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Closure& callback,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For Stub purposes, default to a Wifi scan.
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string device_type = flimflam::kTypeWifi;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!type.empty())
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device_type = type;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShillDeviceClient::TestInterface* device_client =
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string device_path = device_client->GetDevicePathForType(device_type);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!device_path.empty()) {
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device_client->SetDeviceProperty(device_path,
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     flimflam::kScanningProperty,
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FundamentalValue(true));
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kScanDurationSeconds = 3;
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int scan_duration_seconds = kScanDurationSeconds;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::switches::kEnableStubInteractive)) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scan_duration_seconds = 0;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MessageLoop::current()->PostDelayedTask(
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ShillManagerClientStub::ScanCompleted,
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), device_path, callback),
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::TimeDelta::FromSeconds(scan_duration_seconds));
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::EnableTechnology(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& type,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list)) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!error_callback.is_null()) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MessageLoop::current()->PostTask(FROM_HERE, callback);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MessageLoop::current()->PostTask(
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(error_callback, "StubError", "Property not found"));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const int kEnableTechnologyDelaySeconds = 3;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MessageLoop::current()->PostDelayedTask(
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ShillManagerClientStub::SetTechnologyEnabled,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, true),
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::TimeDelta::FromSeconds(kEnableTechnologyDelaySeconds));
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetTechnologyEnabled(type, callback, true);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::DisableTechnology(
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& type,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list)) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!error_callback.is_null()) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MessageLoop::current()->PostTask(
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(error_callback, "StubError", "Property not found"));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const int kDisableTechnologyDelaySeconds = 3;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MessageLoop::current()->PostDelayedTask(
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ShillManagerClientStub::SetTechnologyEnabled,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, false),
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::TimeDelta::FromSeconds(kDisableTechnologyDelaySeconds));
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetTechnologyEnabled(type, callback, false);
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ConfigureService(
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& properties,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ObjectPathCallback& callback,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShillServiceClient::TestInterface* service_client =
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string guid;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string type;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!properties.GetString(flimflam::kGuidProperty, &guid) ||
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !properties.GetString(flimflam::kTypeProperty, &type)) {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the properties aren't filled out completely, then just return an empty
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // object path.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageLoop::current()->PostTask(
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For the purposes of this stub, we're going to assume that the GUID property
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is set to the service path because we don't want to re-implement Shill's
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // property matching magic here.
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string service_path = guid;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string ipconfig_path;
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Merge the new properties with existing properties, if any.
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* existing_properties =
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      service_client->GetServiceProperties(service_path);
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!existing_properties) {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Add a new service to the service client stub because none exists, yet.
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    service_client->AddServiceWithIPConfig(service_path, guid, type,
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           flimflam::kStateIdle, ipconfig_path,
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           true);  // Add service to watch list.
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    existing_properties = service_client->GetServiceProperties(service_path);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged_properties(
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      existing_properties->DeepCopy());
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merged_properties->MergeDictionary(&properties);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now set all the properties.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::DictionaryValue::Iterator iter(*merged_properties);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    service_client->SetServiceProperty(service_path, iter.key(), iter.value());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShillProfileClient::TestInterface* profile_test =
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_test->AddService(service_path);
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ConfigureServiceForProfile(
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue& properties,
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ObjectPathCallback& callback,
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string profile_property;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty,
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           &profile_property);
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(profile_property == profile_path.value());
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConfigureService(properties, callback, error_callback);
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetService(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& properties,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ObjectPathCallback& callback,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyDestination(
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& certificate,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& public_key,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& nonce,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signed_data,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_serial,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BooleanCallback& callback,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, true));
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyAndEncryptCredentials(
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& certificate,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& public_key,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& nonce,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signed_data,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_serial,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& service_path,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StringCallback& callback,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, "encrypted_credentials"));
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyAndEncryptData(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& certificate,
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& public_key,
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& nonce,
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signed_data,
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_serial,
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& data,
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StringCallback& callback,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.is_null())
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostTask(
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, "encrypted_data"));
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ConnectToBestServices(
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClient::TestInterface* ShillManagerClientStub::GetTestInterface() {
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShillManagerClient::TestInterface overrides.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddDevice(const std::string& device_path) {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kDevicesProperty)->AppendIfNotPresent(
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Value::CreateStringValue(device_path))) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemoveDevice(const std::string& device_path) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue device_path_value(device_path);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kDevicesProperty)->Remove(
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_path_value, NULL)) {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ClearDevices() {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.Remove(flimflam::kDevicesProperty, NULL);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ClearServices() {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.Remove(flimflam::kServicesProperty, NULL);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.Remove(flimflam::kServiceWatchListProperty, NULL);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddService(const std::string& service_path,
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool add_to_watch_list) {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent(
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Value::CreateStringValue(service_path))) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (add_to_watch_list)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddServiceToWatchList(service_path);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddServiceAtIndex(const std::string& service_path,
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               size_t index,
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               bool add_to_watch_list) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue path_value(service_path);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* service_list =
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetListProperty(flimflam::kServicesProperty);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue::iterator iter =
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::find_if(service_list->begin(), service_list->end(),
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   ValueEquals(&path_value));
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != service_list->end())
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_list->Erase(iter, NULL);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_list->Insert(index, path_value.DeepCopy());
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (add_to_watch_list)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddServiceToWatchList(service_path);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemoveService(const std::string& service_path) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue service_path_value(service_path);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kServicesProperty)->Remove(
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_path_value, NULL)) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kServiceWatchListProperty)->Remove(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_path_value, NULL)) {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kServiceWatchListProperty, 0);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddTechnology(const std::string& type,
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           bool enabled) {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kAvailableTechnologiesProperty)->
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kAvailableTechnologiesProperty, 0);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled &&
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetListProperty(flimflam::kEnabledTechnologiesProperty)->
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kEnabledTechnologiesProperty, 0);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemoveTechnology(const std::string& type) {
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue type_value(type);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kAvailableTechnologiesProperty)->Remove(
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type_value, NULL)) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kAvailableTechnologiesProperty, 0);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kEnabledTechnologiesProperty)->Remove(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type_value, NULL)) {
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kEnabledTechnologiesProperty, 0);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::SetTechnologyInitializing(const std::string& type,
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       bool initializing) {
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (initializing) {
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AppendIfNotPresent(base::Value::CreateStringValue(type))) {
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::StringValue(type), NULL)) {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ClearProperties() {
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.Clear();
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddGeoNetwork(
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& technology,
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& network) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* list_value = NULL;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_geo_networks_.GetListWithoutPathExpansion(
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      technology, &list_value)) {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list_value = new base::ListValue;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list_value->Append(network.DeepCopy());
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddServiceToWatchList(
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& service_path) {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kServiceWatchListProperty)->AppendIfNotPresent(
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Value::CreateStringValue(service_path))) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kServiceWatchListProperty, 0);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::SetDefaultProperties() {
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Stub Technologies.
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          chromeos::switches::kDisableStubEthernet)) {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddTechnology(flimflam::kTypeEthernet, true);
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddTechnology(flimflam::kTypeWifi, true);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddTechnology(flimflam::kTypeCellular, true);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::PassStubProperties(
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> stub_properties(
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stub_properties_.DeepCopy());
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove disabled services from the list
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kServicesProperty,
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetEnabledServiceList(flimflam::kServicesProperty));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kServiceWatchListProperty,
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetEnabledServiceList(flimflam::kServiceWatchListProperty));
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::PassStubGeoNetworks(
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::CallNotifyObserversPropertyChanged(
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property,
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int delay_ms) {
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Don't actually delay unless we're interactive.
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::switches::kEnableStubInteractive)) {
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delay_ms = 0;
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Avoid unnecessary delayed task if we have no observers (e.g. during
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initial setup).
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (observer_list_.size() == 0)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delay_ms = 0;
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageLoop::current()->PostDelayedTask(
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ShillManagerClientStub::NotifyObserversPropertyChanged,
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 property),
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::TimeDelta::FromMilliseconds(delay_ms));
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::NotifyObserversPropertyChanged(
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (property == flimflam::kServicesProperty ||
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      property == flimflam::kServiceWatchListProperty) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      observer_list_,
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      OnPropertyChanged(property, *(services.get())));
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Value* value = NULL;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Notify for unknown property: " << property;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnPropertyChanged(property, *value));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ListValue* ShillManagerClientStub::GetListProperty(
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* list_property = NULL;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      property, &list_property)) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list_property = new base::ListValue;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stub_properties_.SetWithoutPathExpansion(property, list_property);
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return list_property;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShillManagerClientStub::TechnologyEnabled(const std::string& type) const {
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type == flimflam::kTypeVPN)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;  // VPN is always "enabled" since there is no associated device
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool enabled = false;
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* technologies;
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          flimflam::kEnabledTechnologiesProperty, &technologies)) {
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::StringValue type_value(type);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (technologies->Find(type_value) != technologies->end())
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enabled = true;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return enabled;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::SetTechnologyEnabled(
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& type,
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool enabled) {
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stub_properties_.GetListWithoutPathExpansion(
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list);
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(enabled_list);
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (enabled)
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    enabled_list->AppendIfNotPresent(new base::StringValue(type));
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    enabled_list->Remove(base::StringValue(type), NULL);
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, 0 /* already delayed */);
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!callback.is_null())
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MessageLoop::current()->PostTask(FROM_HERE, callback);
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // May affect available services
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty, 0);
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ListValue* ShillManagerClientStub::GetEnabledServiceList(
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) const {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* new_service_list = new base::ListValue;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* service_list;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillServiceClient::TestInterface* service_client =
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (base::ListValue::const_iterator iter = service_list->begin();
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         iter != service_list->end(); ++iter) {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string service_path;
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*iter)->GetAsString(&service_path))
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue* properties =
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          service_client->GetServiceProperties(service_path);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!properties) {
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(ERROR) << "Properties not found for service: " << service_path;
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string name;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      properties->GetString(flimflam::kNameProperty, &name);
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string type;
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      properties->GetString(flimflam::kTypeProperty, &type);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (TechnologyEnabled(type))
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new_service_list->Append((*iter)->DeepCopy());
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new_service_list;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ScanCompleted(const std::string& device_path,
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           const base::Closure& callback) {
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!device_path.empty()) {
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SetDeviceProperty(device_path,
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          flimflam::kScanningProperty,
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          base::FundamentalValue(false));
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty,
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     0);
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!callback.is_null())
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MessageLoop::current()->PostTask(FROM_HERE, callback);
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
617