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/command_line.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/shill_device_client.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/shill_profile_client.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/shill_service_client.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_path.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_proxy.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/values_util.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to compare values for finding entries to erase in a ListValue.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (ListValue only implements a const_iterator version of Find).
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ValueEquals {
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  explicit ValueEquals(const base::Value* first) : first_(first) {}
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool operator()(const base::Value* second) const {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return first_->Equals(second);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::Value* first_;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Appends string entries from |service_list_in| whose entries in ServiceClient
393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// have Type |match_type| to either an active list or an inactive list
403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// based on the entry's State.
413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid AppendServicesForType(
423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const base::ListValue* service_list_in,
433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const char* match_type,
443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::vector<std::string>* active_service_list_out,
453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::vector<std::string>* inactive_service_list_out) {
463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ShillServiceClient::TestInterface* service_client =
473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (base::ListValue::const_iterator iter = service_list_in->begin();
493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch       iter != service_list_in->end(); ++iter) {
503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string service_path;
513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (!(*iter)->GetAsString(&service_path))
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      continue;
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const base::DictionaryValue* properties =
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        service_client->GetServiceProperties(service_path);
553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (!properties) {
563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      LOG(ERROR) << "Properties not found for service: " << service_path;
573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      continue;
583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string type;
603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    properties->GetString(flimflam::kTypeProperty, &type);
613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (type != match_type)
623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      continue;
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string state;
643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    properties->GetString(flimflam::kStateProperty, &state);
653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (state == flimflam::kStateOnline ||
663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        state == flimflam::kStateAssociation ||
673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        state == flimflam::kStateConfiguration ||
683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        state == flimflam::kStatePortal ||
693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        state == flimflam::kStateReady) {
703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      active_service_list_out->push_back(service_path);
713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    } else {
723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      inactive_service_list_out->push_back(service_path);
733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClientStub::ShillManagerClientStub()
80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    : weak_ptr_factory_(this) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetDefaultProperties();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClientStub::~ShillManagerClientStub() {}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShillManagerClient overrides.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddPropertyChangedObserver(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.AddObserver(observer);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemovePropertyChangedObserver(
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyChangedObserver* observer) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetProperties(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) {
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &ShillManagerClientStub::PassStubProperties,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetNetworksForGeolocation(
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) {
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &ShillManagerClientStub::PassStubGeoNetworks,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          weak_ptr_factory_.GetWeakPtr(),
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::SetProperty(const std::string& name,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Value& value,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Closure& callback,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CallNotifyObserversPropertyChanged(name, 0);
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RequestScan(const std::string& type,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Closure& callback,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const ErrorCallback& error_callback) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For Stub purposes, default to a Wifi scan.
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string device_type = flimflam::kTypeWifi;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!type.empty())
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device_type = type;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShillDeviceClient::TestInterface* device_client =
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string device_path = device_client->GetDevicePathForType(device_type);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!device_path.empty()) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device_client->SetDeviceProperty(device_path,
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     flimflam::kScanningProperty,
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FundamentalValue(true));
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kScanDurationSeconds = 3;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int scan_duration_seconds = kScanDurationSeconds;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::switches::kEnableStubInteractive)) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scan_duration_seconds = 0;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ShillManagerClientStub::ScanCompleted,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), device_path, callback),
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::TimeDelta::FromSeconds(scan_duration_seconds));
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::EnableTechnology(
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& type,
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list)) {
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->PostTask(
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        FROM_HERE,
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(error_callback, "StubError", "Property not found"));
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 kEnableTechnologyDelaySeconds = 3;
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ShillManagerClientStub::SetTechnologyEnabled,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, true),
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::TimeDelta::FromSeconds(kEnableTechnologyDelaySeconds));
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetTechnologyEnabled(type, callback, true);
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::DisableTechnology(
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& type,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list)) {
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->PostTask(
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        FROM_HERE,
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(error_callback, "StubError", "Property not found"));
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const int kDisableTechnologyDelaySeconds = 3;
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ShillManagerClientStub::SetTechnologyEnabled,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, callback, false),
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::TimeDelta::FromSeconds(kDisableTechnologyDelaySeconds));
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetTechnologyEnabled(type, callback, false);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ConfigureService(
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& properties,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ObjectPathCallback& callback,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShillServiceClient::TestInterface* service_client =
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string guid;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string type;
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!properties.GetString(flimflam::kGuidProperty, &guid) ||
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !properties.GetString(flimflam::kTypeProperty, &type)) {
215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    LOG(ERROR) << "ConfigureService requies GUID and Type to be defined";
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the properties aren't filled out completely, then just return an empty
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // object path.
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->PostTask(
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For the purposes of this stub, we're going to assume that the GUID property
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is set to the service path because we don't want to re-implement Shill's
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // property matching magic here.
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string service_path = guid;
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string ipconfig_path;
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Merge the new properties with existing properties, if any.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* existing_properties =
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      service_client->GetServiceProperties(service_path);
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!existing_properties) {
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Add a new service to the service client stub because none exists, yet.
2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // This calls AddManagerService.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    service_client->AddServiceWithIPConfig(service_path, guid, type,
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           flimflam::kStateIdle, ipconfig_path,
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           true /* visible */,
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           true /* watch */);
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    existing_properties = service_client->GetServiceProperties(service_path);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged_properties(
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      existing_properties->DeepCopy());
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merged_properties->MergeDictionary(&properties);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now set all the properties.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::DictionaryValue::Iterator iter(*merged_properties);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    service_client->SetServiceProperty(service_path, iter.key(), iter.value());
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // If the Profile property is set, add it to ProfileClient.
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string profile_path;
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  merged_properties->GetStringWithoutPathExpansion(flimflam::kProfileProperty,
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   &profile_path);
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile_path.empty()) {
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AddService(profile_path, service_path);
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ConfigureServiceForProfile(
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const dbus::ObjectPath& profile_path,
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue& properties,
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ObjectPathCallback& callback,
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string profile_property;
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty,
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           &profile_property);
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(profile_property == profile_path.value());
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConfigureService(properties, callback, error_callback);
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::GetService(
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& properties,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ObjectPathCallback& callback,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyDestination(
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const VerificationProperties& properties,
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BooleanCallback& callback,
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyAndEncryptCredentials(
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const VerificationProperties& properties,
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& service_path,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StringCallback& callback,
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, "encrypted_credentials"));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::VerifyAndEncryptData(
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const VerificationProperties& properties,
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& data,
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StringCallback& callback,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ErrorCallback& error_callback) {
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                   base::Bind(callback, "encrypted_data"));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ConnectToBestServices(
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShillManagerClient::TestInterface* ShillManagerClientStub::GetTestInterface() {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShillManagerClient::TestInterface overrides.
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddDevice(const std::string& device_path) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kDevicesProperty)->AppendIfNotPresent(
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Value::CreateStringValue(device_path))) {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemoveDevice(const std::string& device_path) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue device_path_value(device_path);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kDevicesProperty)->Remove(
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_path_value, NULL)) {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ClearDevices() {
340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GetListProperty(flimflam::kDevicesProperty)->Clear();
341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddTechnology(const std::string& type,
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           bool enabled) {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kAvailableTechnologiesProperty)->
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kAvailableTechnologiesProperty, 0);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled &&
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetListProperty(flimflam::kEnabledTechnologiesProperty)->
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendIfNotPresent(base::Value::CreateStringValue(type))) {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kEnabledTechnologiesProperty, 0);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::RemoveTechnology(const std::string& type) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringValue type_value(type);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kAvailableTechnologiesProperty)->Remove(
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type_value, NULL)) {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kAvailableTechnologiesProperty, 0);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetListProperty(flimflam::kEnabledTechnologiesProperty)->Remove(
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type_value, NULL)) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        flimflam::kEnabledTechnologiesProperty, 0);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::SetTechnologyInitializing(const std::string& type,
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       bool initializing) {
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (initializing) {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AppendIfNotPresent(base::Value::CreateStringValue(type))) {
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::StringValue(type), NULL)) {
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CallNotifyObserversPropertyChanged(
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          shill::kUninitializedTechnologiesProperty, 0);
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::ClearProperties() {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties_.Clear();
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ShillManagerClientStub::AddManagerService(const std::string& service_path,
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                               bool add_to_visible_list,
396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                               bool add_to_watch_list) {
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Always add to ServiceCompleteListProperty.
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetListProperty(shill::kServiceCompleteListProperty)->AppendIfNotPresent(
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Value::CreateStringValue(service_path));
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // If visible, add to Services and notify if new.
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (add_to_visible_list &&
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent(
403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Value::CreateStringValue(service_path))) {
404a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
405a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
406a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (add_to_watch_list)
407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddServiceToWatchList(service_path);
408a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
409a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
410a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ShillManagerClientStub::RemoveManagerService(
411a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string& service_path) {
412a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::StringValue service_path_value(service_path);
413a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (GetListProperty(flimflam::kServicesProperty)->Remove(
414a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      service_path_value, NULL)) {
415a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetListProperty(shill::kServiceCompleteListProperty)->Remove(
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      service_path_value, NULL);
419a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (GetListProperty(flimflam::kServiceWatchListProperty)->Remove(
420a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      service_path_value, NULL)) {
421a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallNotifyObserversPropertyChanged(
422a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        flimflam::kServiceWatchListProperty, 0);
423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
426a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ShillManagerClientStub::ClearManagerServices() {
427a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GetListProperty(flimflam::kServicesProperty)->Clear();
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetListProperty(shill::kServiceCompleteListProperty)->Clear();
429a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GetListProperty(flimflam::kServiceWatchListProperty)->Clear();
430a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
431a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty, 0);
432a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
433a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
4343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ShillManagerClientStub::SortManagerServices() {
4353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  static const char* ordered_types[] = {
4363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    flimflam::kTypeEthernet,
4373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    flimflam::kTypeWifi,
4383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    flimflam::kTypeCellular,
4393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    flimflam::kTypeWimax,
4403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    flimflam::kTypeVPN
4413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  };
4423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::ListValue* service_list = GetListProperty(flimflam::kServicesProperty);
4433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!service_list || service_list->empty())
4443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
4453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<std::string> active_services;
4463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<std::string> inactive_services;
4473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < arraysize(ordered_types); ++i) {
4483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    AppendServicesForType(service_list, ordered_types[i],
4493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                          &active_services, &inactive_services);
4503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
4513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  service_list->Clear();
4523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < active_services.size(); ++i)
4533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    service_list->AppendString(active_services[i]);
4543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < inactive_services.size(); ++i)
4553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    service_list->AppendString(inactive_services[i]);
4563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
4583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddGeoNetwork(
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& technology,
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& network) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* list_value = NULL;
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_geo_networks_.GetListWithoutPathExpansion(
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      technology, &list_value)) {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list_value = new base::ListValue;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list_value->Append(network.DeepCopy());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShillManagerClientStub::AddProfile(const std::string& profile_path) {
473b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const char* key = flimflam::kProfilesProperty;
474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (GetListProperty(key)->AppendIfNotPresent(
475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          new base::StringValue(profile_path))) {
476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    CallNotifyObserversPropertyChanged(key, 0);
477b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
478b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::AddServiceToWatchList(
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& service_path) {
482a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Remove and insert the service, moving it to the front of the watch list.
483a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GetListProperty(flimflam::kServiceWatchListProperty)->Remove(
484a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::StringValue(service_path), NULL);
485a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GetListProperty(flimflam::kServiceWatchListProperty)->Insert(
486a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      0, base::Value::CreateStringValue(service_path));
487a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CallNotifyObserversPropertyChanged(
488a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      flimflam::kServiceWatchListProperty, 0);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::SetDefaultProperties() {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Stub Technologies.
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          chromeos::switches::kDisableStubEthernet)) {
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddTechnology(flimflam::kTypeEthernet, true);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddTechnology(flimflam::kTypeWifi, true);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddTechnology(flimflam::kTypeCellular, true);
4992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  AddTechnology(flimflam::kTypeWimax, true);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::PassStubProperties(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> stub_properties(
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stub_properties_.DeepCopy());
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Remove disabled services from the list.
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kServicesProperty,
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetEnabledServiceList(flimflam::kServicesProperty));
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_properties->SetWithoutPathExpansion(
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flimflam::kServiceWatchListProperty,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetEnabledServiceList(flimflam::kServiceWatchListProperty));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::PassStubGeoNetworks(
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::CallNotifyObserversPropertyChanged(
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property,
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int delay_ms) {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Avoid unnecessary delayed task if we have no observers (e.g. during
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initial setup).
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (observer_list_.size() == 0)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          chromeos::switches::kEnableStubInteractive)) {
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delay_ms = 0;
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ShillManagerClientStub::NotifyObserversPropertyChanged,
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 property),
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::TimeDelta::FromMilliseconds(delay_ms));
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillManagerClientStub::NotifyObserversPropertyChanged(
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (property == flimflam::kServicesProperty ||
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      property == flimflam::kServiceWatchListProperty) {
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      observer_list_,
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      OnPropertyChanged(property, *(services.get())));
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Value* value = NULL;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Notify for unknown property: " << property;
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnPropertyChanged(property, *value));
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ListValue* ShillManagerClientStub::GetListProperty(
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) {
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* list_property = NULL;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stub_properties_.GetListWithoutPathExpansion(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      property, &list_property)) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list_property = new base::ListValue;
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stub_properties_.SetWithoutPathExpansion(property, list_property);
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return list_property;
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShillManagerClientStub::TechnologyEnabled(const std::string& type) const {
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type == flimflam::kTypeVPN)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;  // VPN is always "enabled" since there is no associated device
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool enabled = false;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* technologies;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          flimflam::kEnabledTechnologiesProperty, &technologies)) {
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::StringValue type_value(type);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (technologies->Find(type_value) != technologies->end())
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enabled = true;
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return enabled;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::SetTechnologyEnabled(
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& type,
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool enabled) {
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ListValue* enabled_list = NULL;
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stub_properties_.GetListWithoutPathExpansion(
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, &enabled_list);
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(enabled_list);
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (enabled)
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    enabled_list->AppendIfNotPresent(new base::StringValue(type));
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    enabled_list->Remove(base::StringValue(type), NULL);
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      flimflam::kEnabledTechnologiesProperty, 0 /* already delayed */);
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // May affect available services
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty, 0);
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ListValue* ShillManagerClientStub::GetEnabledServiceList(
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& property) const {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* new_service_list = new base::ListValue;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* service_list;
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillServiceClient::TestInterface* service_client =
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (base::ListValue::const_iterator iter = service_list->begin();
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         iter != service_list->end(); ++iter) {
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string service_path;
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*iter)->GetAsString(&service_path))
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue* properties =
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          service_client->GetServiceProperties(service_path);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!properties) {
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(ERROR) << "Properties not found for service: " << service_path;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string name;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      properties->GetString(flimflam::kNameProperty, &name);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string type;
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      properties->GetString(flimflam::kTypeProperty, &type);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (TechnologyEnabled(type))
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new_service_list->Append((*iter)->DeepCopy());
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new_service_list;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShillManagerClientStub::ScanCompleted(const std::string& device_path,
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           const base::Closure& callback) {
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!device_path.empty()) {
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SetDeviceProperty(device_path,
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          flimflam::kScanningProperty,
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          base::FundamentalValue(false));
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0);
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty,
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     0);
6457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
649