shill_property_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/shill_property_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/format_macros.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stringprintf.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_device_client.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_ipconfig_client.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_manager_client.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_service_client.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_event_log.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLogModule[] = "ShillPropertyHandler";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Limit the number of services or devices we observe. Since they are listed in
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// priority order, it should be reasonable to ignore services past this.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kMaxObserved = 100;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::ListValue* GetListValue(const std::string& key,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const base::Value& value) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::ListValue* vlist = NULL;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value.GetAsList(&vlist)) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Error parsing key as list: " << key;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return vlist;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Class to manage Shill service property changed observers. Observers are
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// added on construction and removed on destruction. Runs the handler when
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OnPropertyChanged is called.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShillPropertyObserver : public ShillPropertyChangedObserver {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(ManagedState::ManagedType type,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& service,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& name,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const base::Value& value)> Handler;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShillPropertyObserver(ManagedState::ManagedType type,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        const std::string& path,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        const Handler& handler)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : type_(type),
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        path_(path),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        handler_(handler) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (type_ == ManagedState::MANAGED_TYPE_NETWORK) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddPropertyChangedObserver(dbus::ObjectPath(path_), this);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (type_ == ManagedState::MANAGED_TYPE_DEVICE) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillDeviceClient()->
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddPropertyChangedObserver(dbus::ObjectPath(path_), this);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ShillPropertyObserver() {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (type_ == ManagedState::MANAGED_TYPE_NETWORK) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillServiceClient()->
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          RemovePropertyChangedObserver(dbus::ObjectPath(path_), this);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (type_ == ManagedState::MANAGED_TYPE_DEVICE) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillDeviceClient()->
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          RemovePropertyChangedObserver(dbus::ObjectPath(path_), this);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ShillPropertyChangedObserver overrides.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPropertyChanged(const std::string& key,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const base::Value& value) OVERRIDE {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    handler_.Run(type_, path_, key, value);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ManagedState::ManagedType type_;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string path_;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Handler handler_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ShillPropertyObserver);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShillPropertyHandler
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillPropertyHandler::ShillPropertyHandler(Listener* listener)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_(listener),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shill_manager_(DBusThreadManager::Get()->GetShillManagerClient()),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillPropertyHandler::~ShillPropertyHandler() {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete network service observers.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      observed_networks_.begin(), observed_networks_.end());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteContainerPairSecondPointers(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      observed_devices_.begin(), observed_devices_.end());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(shill_manager_ == DBusThreadManager::Get()->GetShillManagerClient());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shill_manager_->RemovePropertyChangedObserver(this);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::Init() {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shill_manager_->GetProperties(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ShillPropertyHandler::ManagerPropertiesCallback,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shill_manager_->AddPropertyChangedObserver(this);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShillPropertyHandler::TechnologyAvailable(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& technology) const {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return available_technologies_.count(technology) != 0;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShillPropertyHandler::TechnologyEnabled(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& technology) const {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return enabled_technologies_.count(technology) != 0;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShillPropertyHandler::TechnologyUninitialized(
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& technology) const {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return uninitialized_technologies_.count(technology) != 0;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::SetTechnologyEnabled(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& technology,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool enabled,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const network_handler::ErrorCallback& error_callback) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enabled) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shill_manager_->EnableTechnology(
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        technology,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&base::DoNothing),
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&network_handler::ShillErrorCallbackFunction,
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   kLogModule, technology, error_callback));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shill_manager_->DisableTechnology(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        technology,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&base::DoNothing),
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&network_handler::ShillErrorCallbackFunction,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   kLogModule, technology, error_callback));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::RequestScan() const {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shill_manager_->RequestScan(
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "",
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&base::DoNothing),
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&network_handler::ShillErrorCallbackFunction,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 kLogModule, "", network_handler::ErrorCallback()));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::RequestProperties(ManagedState::ManagedType type,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const std::string& path) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_updates_[type].find(path) != pending_updates_[type].end())
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;  // Update already requested.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_updates_[type].insert(path);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == ManagedState::MANAGED_TYPE_NETWORK) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetShillServiceClient()->GetProperties(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectPath(path),
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ShillPropertyHandler::GetPropertiesCallback,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, path));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties(
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectPath(path),
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ShillPropertyHandler::GetPropertiesCallback,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), type, path));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::OnPropertyChanged(const std::string& key,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const base::Value& value) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ManagerPropertyChanged(key, value))
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->ManagerPropertyChanged();
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the service watch or device list changed and there are no pending
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // updates, signal the state list changed callback.
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if ((key == flimflam::kServiceWatchListProperty) &&
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0) {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_NETWORK);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (key == flimflam::kDevicesProperty &&
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_updates_[ManagedState::MANAGED_TYPE_DEVICE].size() == 0) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_DEVICE);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Private methods
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::ManagerPropertiesCallback(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusMethodCallStatus call_status,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& properties) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (call_status != DBUS_METHOD_CALL_SUCCESS) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to get Manager properties:" << call_status;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool notify = false;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool update_service_list = false;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::DictionaryValue::Iterator iter(properties);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter.HasNext(); iter.Advance()) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Defer updating Services until all other properties have been updated.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter.key() == flimflam::kServicesProperty)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_service_list = true;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify |= ManagerPropertyChanged(iter.key(), iter.value());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now update the service list which can safely assume other properties have
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been initially set.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_service_list) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* value = NULL;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (properties.GetWithoutPathExpansion(flimflam::kServicesProperty, &value))
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify |= ManagerPropertyChanged(flimflam::kServicesProperty, *value);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (notify)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->ManagerPropertyChanged();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are no pending updates, signal the state list changed callbacks.
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_updates_[ManagedState::MANAGED_TYPE_NETWORK].size() == 0)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_NETWORK);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_updates_[ManagedState::MANAGED_TYPE_DEVICE].size() == 0)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    listener_->ManagedStateListChanged(ManagedState::MANAGED_TYPE_DEVICE);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShillPropertyHandler::ManagerPropertyChanged(const std::string& key,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  const base::Value& value) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool notify_manager_changed = false;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key == flimflam::kServicesProperty) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* vlist = GetListValue(key, value);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vlist)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      listener_->UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, *vlist);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (key == flimflam::kServiceWatchListProperty) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* vlist = GetListValue(key, value);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vlist) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateObserved(ManagedState::MANAGED_TYPE_NETWORK, *vlist);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (key == flimflam::kDevicesProperty) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ListValue* vlist = GetListValue(key, value);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (vlist) {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      listener_->UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, *vlist);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateObserved(ManagedState::MANAGED_TYPE_DEVICE, *vlist);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (key == flimflam::kAvailableTechnologiesProperty) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* vlist = GetListValue(key, value);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (vlist) {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateAvailableTechnologies(*vlist);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify_manager_changed = true;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (key == flimflam::kEnabledTechnologiesProperty) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* vlist = GetListValue(key, value);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vlist) {
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateEnabledTechnologies(*vlist);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notify_manager_changed = true;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (key == shill::kUninitializedTechnologiesProperty) {
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* vlist = GetListValue(key, value);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (vlist) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateUninitializedTechnologies(*vlist);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify_manager_changed = true;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notify_manager_changed;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::UpdateObserved(ManagedState::ManagedType type,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const base::ListValue& entries) {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShillPropertyObserverMap& observer_map =
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (type == ManagedState::MANAGED_TYPE_NETWORK)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ? observed_networks_ : observed_devices_;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShillPropertyObserverMap new_observed;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator iter1 = entries.begin();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter1 != entries.end(); ++iter1) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*iter1)->GetAsString(&path);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (path.empty())
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShillPropertyObserverMap::iterator iter2 = observer_map.find(path);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter2 != observer_map.end()) {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_observed[path] = iter2->second;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Request an update.
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RequestProperties(type, path);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Create an observer for future updates.
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_observed[path] = new ShillPropertyObserver(
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type, path, base::Bind(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              &ShillPropertyHandler::PropertyChangedCallback,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              weak_ptr_factory_.GetWeakPtr()));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      network_event_log::AddEntry(kLogModule, "StartObserving", path);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer_map.erase(path);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Limit the number of observed services.
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (new_observed.size() >= kMaxObserved)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete network service observers still in observer_map.
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ShillPropertyObserverMap::iterator iter =  observer_map.begin();
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != observer_map.end(); ++iter) {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    network_event_log::AddEntry(kLogModule, "StopObserving", iter->first);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete iter->second;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_map.swap(new_observed);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::UpdateAvailableTechnologies(
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue& technologies) {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  available_technologies_.clear();
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  network_event_log::AddEntry(
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLogModule, "AvailableTechnologiesChanged",
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringPrintf("Size: %"PRIuS, technologies.GetSize()));
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::ListValue::const_iterator iter = technologies.begin();
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != technologies.end(); ++iter) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string technology;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->GetAsString(&technology);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!technology.empty());
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    available_technologies_.insert(technology);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::UpdateEnabledTechnologies(
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue& technologies) {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enabled_technologies_.clear();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  network_event_log::AddEntry(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLogModule, "EnabledTechnologiesChanged",
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringPrintf("Size: %"PRIuS, technologies.GetSize()));
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::ListValue::const_iterator iter = technologies.begin();
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != technologies.end(); ++iter) {
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string technology;
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->GetAsString(&technology);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!technology.empty());
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enabled_technologies_.insert(technology);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::UpdateUninitializedTechnologies(
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue& technologies) {
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uninitialized_technologies_.clear();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  network_event_log::AddEntry(
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLogModule, "UninitializedTechnologiesChanged",
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringPrintf("Size: %"PRIuS, technologies.GetSize()));
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::ListValue::const_iterator iter = technologies.begin();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != technologies.end(); ++iter) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string technology;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->GetAsString(&technology);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!technology.empty());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uninitialized_technologies_.insert(technology);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::GetPropertiesCallback(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState::ManagedType type,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusMethodCallStatus call_status,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& properties) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "GetPropertiesCallback: " << type << " : " << path;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_updates_[type].erase(path);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (call_status != DBUS_METHOD_CALL_SUCCESS) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to get properties for: " << path
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << ": " << call_status;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_->UpdateManagedStateProperties(type, path, properties);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (properties.HasKey(shill::kIPConfigProperty)) {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since this is the first time we received properties for this network,
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // also request its IPConfig parameters.
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string ip_config_path;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (properties.GetString(shill::kIPConfigProperty, &ip_config_path)) {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dbus::ObjectPath(ip_config_path),
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&ShillPropertyHandler::GetIPConfigCallback,
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(), path));
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the listener only when all updates for that type have completed.
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_updates_[type].size() == 0)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->ManagedStateListChanged(type);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::PropertyChangedCallback(
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ManagedState::ManagedType type,
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& key,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Value& value) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type == ManagedState::MANAGED_TYPE_NETWORK)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetworkServicePropertyChangedCallback(path, key, value);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (type == ManagedState::MANAGED_TYPE_DEVICE)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetworkDevicePropertyChangedCallback(path, key, value);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::NetworkServicePropertyChangedCallback(
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (key == shill::kIPConfigProperty) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Handle IPConfig here and call listener_->UpdateNetworkServiceIPAddress
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when the request completes.
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string ip_config_path;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    value.GetAsString(&ip_config_path);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!ip_config_path.empty());
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dbus::ObjectPath(ip_config_path),
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ShillPropertyHandler::GetIPConfigCallback,
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), path));
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    listener_->UpdateNetworkServiceProperty(path, key, value);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillPropertyHandler::GetIPConfigCallback(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& service_path,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusMethodCallStatus call_status,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& properties)  {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (call_status != DBUS_METHOD_CALL_SUCCESS) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to get IP properties for: " << service_path;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string ip_address;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!properties.GetStringWithoutPathExpansion(flimflam::kAddressProperty,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                &ip_address)) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to get IP Address property for: " << service_path;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_->UpdateNetworkServiceIPAddress(service_path, ip_address);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShillPropertyHandler::NetworkDevicePropertyChangedCallback(
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& key,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Value& value) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listener_->UpdateDeviceProperty(path, key, value);
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
452