real_shill_provider.cc revision df3dd2438aef108ac66dc42a4eabae8c79ee88a3
155f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
255f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold// Use of this source code is governed by a BSD-style license that can be
355f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold// found in the LICENSE file.
455f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
555f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold#include "update_engine/policy_manager/real_shill_provider.h"
655f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
75ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <string>
85ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
95ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <base/logging.h>
1075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h>
115ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <chromeos/dbus/service_constants.h>
125ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
135ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include "update_engine/policy_manager/generic_variables.h"
145ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include "update_engine/utils.h"
155ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
165ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldusing std::string;
175ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
185ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldnamespace {
195ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
20df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnoldconst char* kConnInfoNotAvailErrMsg = "Connection information not available";
21df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold
225ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold// Looks up a key in a hash table and returns the string inside of the returned
235ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold// GValue.
245ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldconst char* GetStrProperty(GHashTable* hash_table, const char* key) {
255ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  auto gval = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table, key));
265ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  return (gval ? g_value_get_string(gval) : NULL);
275ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
285ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
295ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold};  // namespace
305ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
315ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
3255f39b7043fae6b7c27188d0cd797946098b42efGilad Arnoldnamespace chromeos_policy_manager {
3355f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
34beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold// ShillConnector methods.
35beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
365ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldconst ShillConnector::ConnStrToType ShillConnector::shill_conn_str_to_type[] = {
37af309d513504683bbcfb0bfac71652999845555fGilad Arnold  {shill::kTypeEthernet, ConnectionType::kEthernet},
38af309d513504683bbcfb0bfac71652999845555fGilad Arnold  {shill::kTypeWifi, ConnectionType::kWifi},
39af309d513504683bbcfb0bfac71652999845555fGilad Arnold  {shill::kTypeWimax, ConnectionType::kWimax},
40af309d513504683bbcfb0bfac71652999845555fGilad Arnold  {shill::kTypeBluetooth, ConnectionType::kBluetooth},
41af309d513504683bbcfb0bfac71652999845555fGilad Arnold  {shill::kTypeCellular, ConnectionType::kCellular},
425ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold};
435ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
44beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad ArnoldShillConnector::~ShillConnector() {
45beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  if (!is_init_)
46beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    return;
47beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
48beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Detach signal handler, free manager proxy.
49beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  dbus_->ProxyDisconnectSignal(manager_proxy_, shill::kMonitorPropertyChanged,
50beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                               G_CALLBACK(signal_handler_), signal_data_);
51beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  dbus_->ProxyUnref(manager_proxy_);
52beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold}
53beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
545ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldbool ShillConnector::Init() {
55beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  if (is_init_)
56beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    return true;
57beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
58beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Obtain a DBus connection.
595ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  GError* error = NULL;
605ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  connection_ = dbus_->BusGet(DBUS_BUS_SYSTEM, &error);
615ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  if (!connection_) {
625ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    LOG(ERROR) << "Failed to initialize DBus connection: "
635ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold               << chromeos_update_engine::utils::GetAndFreeGError(&error);
645ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    return false;
655ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  }
66beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
67beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Allocate a shill manager proxy.
685ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  manager_proxy_ = GetProxy(shill::kFlimflamServicePath,
695ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold                            shill::kFlimflamManagerInterface);
705ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
71beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Subscribe to the manager's PropertyChanged signal.
72beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  dbus_->ProxyAddSignal_2(manager_proxy_, shill::kMonitorPropertyChanged,
73beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                          G_TYPE_STRING, G_TYPE_VALUE);
74beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  dbus_->ProxyConnectSignal(manager_proxy_, shill::kMonitorPropertyChanged,
75beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                            G_CALLBACK(signal_handler_), signal_data_, NULL);
765ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
77beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  return is_init_ = true;
785ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
795ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
805ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldbool ShillConnector::GetConnectionType(const string& service_path,
81af309d513504683bbcfb0bfac71652999845555fGilad Arnold                                       ConnectionType* conn_type_p) {
825ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  // Obtain a proxy for the service path.
835ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  DBusGProxy* service_proxy = GetProxy(service_path.c_str(),
845ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold                                       shill::kFlimflamServiceInterface);
855ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
865ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  GHashTable* hash_table = NULL;
875ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  bool success = false;
885ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  bool is_vpn = false;
895ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  if (GetProperties(service_proxy, &hash_table)) {
905ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    const char* type_str = GetStrProperty(hash_table, shill::kTypeProperty);
915ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    if (type_str && !strcmp(type_str, shill::kTypeVPN)) {
925ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      is_vpn = true;
935ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      type_str = GetStrProperty(hash_table, shill::kPhysicalTechnologyProperty);
945ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    }
955ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    if (type_str) {
965ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      success = true;
975ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      *conn_type_p = ParseConnType(type_str);
985ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    }
995ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    g_hash_table_unref(hash_table);
1005ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  }
1015ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1025ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  if (!success) {
1035ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    LOG(ERROR) << "Could not find type of "
1045ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold               << (is_vpn ? "physical connection underlying VPN " : "")
1055ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold               << "connection (" << service_path << ")";
1065ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  }
1075ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1085ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  dbus_->ProxyUnref(service_proxy);
1095ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  return success;
1105ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
1115ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1125ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad ArnoldDBusGProxy* ShillConnector::GetProxy(const char* path, const char* interface) {
1135ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  return dbus_->ProxyNewForName(connection_, shill::kFlimflamServiceName,
1145ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold                                path, interface);
1155ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
1165ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
117af309d513504683bbcfb0bfac71652999845555fGilad ArnoldConnectionType ShillConnector::ParseConnType(const char* str) {
1185ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  for (unsigned i = 0; i < arraysize(shill_conn_str_to_type); i++)
1195ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    if (!strcmp(str, shill_conn_str_to_type[i].str))
1205ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      return shill_conn_str_to_type[i].type;
1215ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
122af309d513504683bbcfb0bfac71652999845555fGilad Arnold  return ConnectionType::kUnknown;
1235ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
1245ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1255ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldbool ShillConnector::GetProperties(DBusGProxy* proxy, GHashTable** result_p) {
1265ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  GError* error = NULL;
1275ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  if (!dbus_->ProxyCall_0_1(proxy, shill::kGetPropertiesFunction, &error,
1285ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold                            result_p)) {
1295ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    LOG(ERROR) << "Calling shill via DBus proxy failed: "
1305ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold               << chromeos_update_engine::utils::GetAndFreeGError(&error);
1315ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    return false;
1325ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  }
1335ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  return true;
1345ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold}
1355ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1365ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1375ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold// A variable returning the curent connection type.
138af309d513504683bbcfb0bfac71652999845555fGilad Arnoldclass ConnTypeVariable : public Variable<ConnectionType> {
1395ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold public:
1405ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  ConnTypeVariable(const string& name, ShillConnector* connector,
141beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                   RealShillProvider* provider)
142af309d513504683bbcfb0bfac71652999845555fGilad Arnold      : Variable<ConnectionType>(name, kVariableModePoll),
143beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold        connector_(connector), provider_(provider) {}
1445ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1455ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold protected:
146beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // TODO(garnold) Shift to a non-blocking version, respect the timeout.
147af309d513504683bbcfb0bfac71652999845555fGilad Arnold  virtual const ConnectionType* GetValue(base::TimeDelta /* timeout */,
148af309d513504683bbcfb0bfac71652999845555fGilad Arnold                                         string* errmsg) {
149df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold    if (!(provider_->is_conn_status_init_)) {
150df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold      if (errmsg)
151df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold        *errmsg = kConnInfoNotAvailErrMsg;
152df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold      return NULL;
153df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold    }
154df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold
155beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    if (!(provider_->is_connected_)) {
156beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      if (errmsg)
157beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold        *errmsg = "No connection detected";
1585ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      return NULL;
159beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    }
160beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
161af309d513504683bbcfb0bfac71652999845555fGilad Arnold    ConnectionType conn_type;
162beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    if (provider_->is_conn_type_valid_) {
163beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      conn_type = provider_->conn_type_;
164beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    } else {
165beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      if (!connector_->GetConnectionType(provider_->default_service_path_,
166beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                         &conn_type)) {
167beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold        if (errmsg)
16875039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko          *errmsg = base::StringPrintf(
169beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold              "Could not retrieve type of default connection (%s)",
170beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold              provider_->default_service_path_.c_str());
171beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold        return NULL;
172beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      }
173beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      provider_->is_conn_type_valid_ = true;
174beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    }
1755ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
176af309d513504683bbcfb0bfac71652999845555fGilad Arnold    return new ConnectionType(conn_type);
1775ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  }
1785ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1795ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold private:
180beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // The DBus connector.
1815ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  ShillConnector* connector_;
182beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
183beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // The shill provider object (we need to read/update some internal members).
184beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  RealShillProvider* provider_;
1855ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold
1865ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  DISALLOW_COPY_AND_ASSIGN(ConnTypeVariable);
1875ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold};
18855f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
189beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
190beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold// RealShillProvider methods.
191beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
1925ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldbool RealShillProvider::DoInit() {
1935ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  // Initialize a DBus connection and obtain the shill manager proxy.
194beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  connector_.reset(new ShillConnector(dbus_, HandlePropertyChangedStatic,
195beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                      this));
1965ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  if (!connector_->Init())
1975ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold    return false;
19855f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
199df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  // Attempt to read initial connection status. Even if this fails because shill
200df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  // is not responding (e.g. it is down) we'll be notified via "PropertyChanged"
201df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  // signal as soon as it comes up, so this is not a critical step.
202beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  GHashTable* hash_table = NULL;
203df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  if (connector_->GetManagerProperties(&hash_table)) {
204df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold    GValue* value = reinterpret_cast<GValue*>(
205df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold        g_hash_table_lookup(hash_table, shill::kDefaultServiceProperty));
206df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold    ProcessDefaultService(value);
207df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold    g_hash_table_unref(hash_table);
208df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  }
209beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
2105ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold  // Initialize variables.
211df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  var_is_connected_.reset(
212df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold      new CopyVariable<bool>("is_connected", kVariableModePoll, is_connected_,
213df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold                             &is_conn_status_init_, kConnInfoNotAvailErrMsg));
214df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  var_conn_type_.reset(
215beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold      new ConnTypeVariable("conn_type", connector_.get(), this));
216df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  var_conn_last_changed_.reset(
2175ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold      new CopyVariable<base::Time>("conn_last_changed", kVariableModePoll,
218df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold                                   conn_last_changed_, &is_conn_status_init_,
219df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold                                   kConnInfoNotAvailErrMsg));
22055f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold  return true;
22155f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold}
22255f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold
223beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnoldbool RealShillProvider::ProcessDefaultService(GValue* value) {
224beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Decode the string from the boxed value.
225beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  const char* default_service_path_str = NULL;
226beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  if (!(value && (default_service_path_str = g_value_get_string(value))))
227beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    return false;
228beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
229beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  // Update the connection status.
230beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  is_connected_ = strcmp(default_service_path_str, "/");
231beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  if (default_service_path_ != default_service_path_str)
232beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    conn_last_changed_ = clock_->GetWallclockTime();
233beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  default_service_path_ = default_service_path_str;
234beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  is_conn_type_valid_ = false;
235df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold
236df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  // Mark the connection status as initialized.
237df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold  is_conn_status_init_ = true;
238beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  return true;
239beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold}
240beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
241beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnoldvoid RealShillProvider::HandlePropertyChanged(DBusGProxy* proxy,
242beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                              const char* name, GValue* value) {
243beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  if (!strcmp(name, shill::kDefaultServiceProperty))
244beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold    ProcessDefaultService(value);
245beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold}
246beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
247beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnoldvoid RealShillProvider::HandlePropertyChangedStatic(DBusGProxy* proxy,
248beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                                    const char* name,
249beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                                    GValue* value,
250beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold                                                    void* data) {
251beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  auto obj = reinterpret_cast<RealShillProvider*>(data);
252beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold  obj->HandlePropertyChanged(proxy, name, value);
253beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold}
254beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold
25555f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold}  // namespace chromeos_policy_manager
256