connection_manager.cc revision d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6
14348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// Use of this source code is governed by a BSD-style license that can be
3d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// found in the LICENSE file.
4d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
54348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan#include "update_engine/connection_manager.h"
6d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
7d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <set>
8d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes#include <string>
9d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
104348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan#include <base/stl_util.h>
1175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/string_util.h>
124348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan#include <chromeos/dbus/service_constants.h>
13d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes#include <dbus/dbus-glib.h>
14d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes#include <glib.h>
151f84723f499b3b309efac11324ed4e6c937341b6Gilad Arnold#include <policy/device_policy.h>
16d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
17f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo#include "update_engine/prefs.h"
184348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan#include "update_engine/system_state.h"
19d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes#include "update_engine/utils.h"
20d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
214348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasanusing std::set;
22d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyesusing std::string;
23d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
24d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyesnamespace chromeos_update_engine {
25d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
26d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyesnamespace {
27d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
28d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// Gets the DbusGProxy for FlimFlam. Must be free'd with ProxyUnref()
291b9d6ae00b3c3badf9785584c2c867710f214a62Gilad Arnoldbool GetFlimFlamProxy(DBusWrapperInterface* dbus_iface,
30d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                      const char* path,
31d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                      const char* interface,
32d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                      DBusGProxy** out_proxy) {
33d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  DBusGConnection* bus;
34d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  DBusGProxy* proxy;
35d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  GError* error = NULL;
36d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
37d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  bus = dbus_iface->BusGet(DBUS_BUS_SYSTEM, &error);
38d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  if (!bus) {
39d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    LOG(ERROR) << "Failed to get system bus";
40d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return false;
41d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
42b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold  proxy = dbus_iface->ProxyNewForName(bus, shill::kFlimflamServiceName, path,
43b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold                                      interface);
44d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  *out_proxy = proxy;
45d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return true;
46d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
47d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
48d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// On success, caller owns the GHashTable at out_hash_table.
49d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// Returns true on success.
501b9d6ae00b3c3badf9785584c2c867710f214a62Gilad Arnoldbool GetProperties(DBusWrapperInterface* dbus_iface,
51d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                   const char* path,
52d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                   const char* interface,
53d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                   GHashTable** out_hash_table) {
54d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  DBusGProxy* proxy;
55d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  GError* error = NULL;
56d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
57d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  TEST_AND_RETURN_FALSE(GetFlimFlamProxy(dbus_iface,
58d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                         path,
59d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                         interface,
60d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                         &proxy));
61d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
62b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold  gboolean rc = dbus_iface->ProxyCall_0_1(proxy,
63b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold                                          "GetProperties",
64b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold                                          &error,
65b752fb342f2d8f9766f13764e4747a50a1195308Gilad Arnold                                          out_hash_table);
66d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  dbus_iface->ProxyUnref(proxy);
67d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  if (rc == FALSE) {
68d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    LOG(ERROR) << "dbus_g_proxy_call failed";
69d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return false;
70d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
71d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
72d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return true;
73d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
74d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
75d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// Returns (via out_path) the default network path, or empty string if
76d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// there's no network up.
77d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes// Returns true on success.
781b9d6ae00b3c3badf9785584c2c867710f214a62Gilad Arnoldbool GetDefaultServicePath(DBusWrapperInterface* dbus_iface, string* out_path) {
79d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  GHashTable* hash_table = NULL;
80d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
81d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
82c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                      shill::kFlimflamServicePath,
83c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                      shill::kFlimflamManagerInterface,
84d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                      &hash_table));
85d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
86d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  GValue* value = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
87d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                                                "Services"));
885665d0ced6812771559ca7bf938fa48f2b93ae48Alex Deymo  GPtrArray* array = NULL;
89d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  bool success = false;
9088226ff9674d5d6250a0c919082e9bd1c93c35bfmukesh agrawal  if (G_VALUE_HOLDS(value, DBUS_TYPE_G_OBJECT_PATH_ARRAY) &&
915665d0ced6812771559ca7bf938fa48f2b93ae48Alex Deymo      (array = reinterpret_cast<GPtrArray*>(g_value_get_boxed(value))) &&
92d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes      (array->len > 0)) {
935665d0ced6812771559ca7bf938fa48f2b93ae48Alex Deymo    *out_path = static_cast<const char*>(g_ptr_array_index(array, 0));
94d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    success = true;
95d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
9688226ff9674d5d6250a0c919082e9bd1c93c35bfmukesh agrawal
97d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  g_hash_table_unref(hash_table);
98d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return success;
99d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
100d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
101d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los ReyesNetworkConnectionType ParseConnectionType(const char* type_str) {
102c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  if (!strcmp(type_str, shill::kTypeEthernet)) {
103d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return kNetEthernet;
104c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  } else if (!strcmp(type_str, shill::kTypeWifi)) {
105d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return kNetWifi;
106c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  } else if (!strcmp(type_str, shill::kTypeWimax)) {
107d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return kNetWimax;
108c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  } else if (!strcmp(type_str, shill::kTypeBluetooth)) {
109d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return kNetBluetooth;
110c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  } else if (!strcmp(type_str, shill::kTypeCellular)) {
111d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return kNetCellular;
112d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
113d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return kNetUnknown;
114d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
115d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
1166ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex DeymoNetworkTethering ParseTethering(const char* tethering_str) {
1176ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  if (!strcmp(tethering_str, shill::kTetheringNotDetectedState)) {
1186ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    return NetworkTethering::kNotDetected;
1196ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  } else if (!strcmp(tethering_str, shill::kTetheringSuspectedState)) {
1206ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    return NetworkTethering::kSuspected;
1216ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  } else if (!strcmp(tethering_str, shill::kTetheringConfirmedState)) {
1226ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    return NetworkTethering::kConfirmed;
1236ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  }
1246ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  LOG(WARNING) << "Unknown Tethering value: " << tethering_str;
1256ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  return NetworkTethering::kUnknown;
1266ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo}
1276ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo
1286ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymobool GetServicePathProperties(DBusWrapperInterface* dbus_iface,
1296ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                              const string& path,
1306ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                              NetworkConnectionType* out_type,
1316ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                              NetworkTethering* out_tethering) {
132d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  GHashTable* hash_table = NULL;
133d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
134d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
135d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                      path.c_str(),
136c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                      shill::kFlimflamServiceInterface,
137d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                      &hash_table));
138d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
1396ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  // Populate the out_tethering.
140d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  GValue* value =
141d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko      reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
142d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko                                                    shill::kTetheringProperty));
1436ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  const char* tethering_str = NULL;
1446ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo
1456ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  if (value != NULL)
1466ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    tethering_str = g_value_get_string(value);
1476ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  if (tethering_str != NULL) {
1486ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    *out_tethering = ParseTethering(tethering_str);
1496ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  } else {
1506ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    // Set to Unknown if not present.
1516ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    *out_tethering = NetworkTethering::kUnknown;
1526ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  }
1536ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo
1546ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  // Populate the out_type property.
155d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  value = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
156d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko                                                        shill::kTypeProperty));
157d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  const char* type_str = NULL;
158d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  bool success = false;
159d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  if (value != NULL && (type_str = g_value_get_string(value)) != NULL) {
160d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    success = true;
161c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan    if (!strcmp(type_str, shill::kTypeVPN)) {
162d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko      value = reinterpret_cast<GValue*>(
163d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko          g_hash_table_lookup(hash_table, shill::kPhysicalTechnologyProperty));
1641c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo      if (value != NULL && (type_str = g_value_get_string(value)) != NULL) {
1651c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo        *out_type = ParseConnectionType(type_str);
1661c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo      } else {
1671c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo        LOG(ERROR) << "No PhysicalTechnology property found for a VPN"
1681c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo                   << " connection (service: " << path << "). Returning default"
1691c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo                   << " kNetUnknown value.";
1701c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo        *out_type = kNetUnknown;
1711c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo      }
1721c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo    } else {
1731c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo      *out_type = ParseConnectionType(type_str);
1741c4e6382a74db329a3cfad10e68dd077cb75e5c4Alex Deymo    }
175d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
176d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  g_hash_table_unref(hash_table);
177d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return success;
178d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
179d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
180d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
181d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
1824348879380222dc8c74b0976e527bf3da66ba08fJay SrinivasanConnectionManager::ConnectionManager(SystemState *system_state)
1834348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    :  system_state_(system_state) {}
1844348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
1856ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymobool ConnectionManager::IsUpdateAllowedOver(NetworkConnectionType type,
1866ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                                            NetworkTethering tethering) const {
1874348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan  switch (type) {
1884348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    case kNetBluetooth:
1894348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      return false;
1904348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
1914348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    case kNetCellular: {
1924348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      set<string> allowed_types;
1934348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      const policy::DevicePolicy* device_policy =
1946f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan          system_state_->device_policy();
195f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
196f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo      // A device_policy is loaded in a lazy way right before an update check,
197f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo      // so the device_policy should be already loaded at this point. If it's
198f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo      // not, return a safe value for this setting.
1994348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      if (!device_policy) {
200f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        LOG(INFO) << "Disabling updates over cellular networks as there's no "
201f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo                     "device policy loaded yet.";
2024348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan        return false;
2034348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      }
2044348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
205f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo      if (device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
206f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        // The update setting is enforced by the device policy.
207f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
2089a423ff19e3a7503cd8128998b3a10d65c499fdcGilad Arnold        if (!ContainsKey(allowed_types, shill::kTypeCellular)) {
209f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          LOG(INFO) << "Disabling updates over cellular connection as it's not "
210f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo                       "allowed in the device policy.";
211f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          return false;
212f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        }
213f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
214f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        LOG(INFO) << "Allowing updates over cellular per device policy.";
215f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        return true;
216f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo      } else {
217f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        // There's no update setting in the device policy, using the local user
218f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        // setting.
219f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        PrefsInterface* prefs = system_state_->prefs();
220f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
221f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        if (!prefs || !prefs->Exists(kPrefsUpdateOverCellularPermission)) {
222f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          LOG(INFO) << "Disabling updates over cellular connection as there's "
223f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo                       "no device policy setting nor user preference present.";
224f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          return false;
225f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        }
226f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
227efb7c4c605440fdc6297deed8fa9d1aecb77235eAlex Deymo        bool stored_value;
228efb7c4c605440fdc6297deed8fa9d1aecb77235eAlex Deymo        if (!prefs->GetBoolean(kPrefsUpdateOverCellularPermission,
229efb7c4c605440fdc6297deed8fa9d1aecb77235eAlex Deymo                               &stored_value)) {
230f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          return false;
231efb7c4c605440fdc6297deed8fa9d1aecb77235eAlex Deymo        }
232f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo
233f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        if (!stored_value) {
234f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          LOG(INFO) << "Disabling updates over cellular connection per user "
235f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo                       "setting.";
236f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo          return false;
237f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        }
238f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        LOG(INFO) << "Allowing updates over cellular per user setting.";
239f4867c4dab4d1ca566f1aa3f585bd16d87b911ddAlex Deymo        return true;
2404348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      }
2414348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    }
2424348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
2434348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    default:
2446ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      if (tethering == NetworkTethering::kConfirmed) {
2456ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo        // Treat this connection as if it is a cellular connection.
2466ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo        LOG(INFO) << "Current connection is confirmed tethered, using Cellular "
2476ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                     "setting.";
2486ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo        return IsUpdateAllowedOver(kNetCellular, NetworkTethering::kUnknown);
2496ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      }
2504348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan      return true;
2514348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan  }
2524348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan}
2534348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
2544348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasanconst char* ConnectionManager::StringForConnectionType(
2554348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan    NetworkConnectionType type) const {
256c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan  static const char* const kValues[] = {shill::kTypeEthernet,
257c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                        shill::kTypeWifi,
258c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                        shill::kTypeWimax,
259c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                        shill::kTypeBluetooth,
260c6007e4fbd9a58ca467fa59feef4a46b8075d434Ben Chan                                        shill::kTypeCellular};
261d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  if (type < 0 || type >= static_cast<int>(arraysize(kValues))) {
262d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    return "Unknown";
263d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
264d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return kValues[type];
265d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
266d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
2676ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymoconst char* ConnectionManager::StringForTethering(
2686ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    NetworkTethering tethering) const {
2696ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  switch (tethering) {
2706ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    case NetworkTethering::kNotDetected:
2716ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      return shill::kTetheringNotDetectedState;
2726ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    case NetworkTethering::kSuspected:
2736ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      return shill::kTetheringSuspectedState;
2746ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    case NetworkTethering::kConfirmed:
2756ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      return shill::kTetheringConfirmedState;
2766ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    case NetworkTethering::kUnknown:
2776ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo      return "Unknown";
2786ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  }
2796ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  // The program shouldn't reach this point, but the compiler isn't smart
2806ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  // enough to infer that.
2816ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  return "Unknown";
2826ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo}
2836ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo
2846ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymobool ConnectionManager::GetConnectionProperties(
2851b9d6ae00b3c3badf9785584c2c867710f214a62Gilad Arnold    DBusWrapperInterface* dbus_iface,
2866ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    NetworkConnectionType* out_type,
2876ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo    NetworkTethering* out_tethering) const {
288d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  string default_service_path;
289d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  TEST_AND_RETURN_FALSE(GetDefaultServicePath(dbus_iface,
290d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes                                              &default_service_path));
2916ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo  TEST_AND_RETURN_FALSE(GetServicePathProperties(dbus_iface,
2926ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                                                 default_service_path,
2936ae9120dc76ce9a3c8d05f71c05f23e3f4bdc6bdAlex Deymo                                                 out_type, out_tethering));
294d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  return true;
295d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
296d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
297d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}  // namespace chromeos_update_engine
298