Treat confirmed Tethered networks as Cellular networks.
The updates are allowed based on the type of connection used to
download it from. For example, by default, no update is made over
Cellular networks even if the device is connected to a VPN over a
Cellular network to prevent huge charges on those connections.
Nevertheless, when the device is connected to a tethered network such
as an Android or iPhone sharing its Cellular connection over Wifi,
the connection type the device sees is a Wifi and thus will allow
the updates by default.
To prevent updates over tethered networks, this patch uses the
Tethering property expossed by shill to avoid those situations. If
the device is connected to a network that shill confirms to be a
tethered network, it will be treated as if the device is connected
to a Cellular network. This means that the updates will be allowed
based on the same settings that govern if the updates are allowed
over Cellular networks.
BUG=chromium:323010
TEST=Unit tests added to verify policy and property parsing.
Change-Id: I3a31c804465c9ed5c76b5d6156adda8e5e4e8a6d
Reviewed-on: https://chromium-review.googlesource.com/189524
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Chris Sosa <sosa@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/connection_manager.cc b/connection_manager.cc
index 97bc1bd..8ac1079 100644
--- a/connection_manager.cc
+++ b/connection_manager.cc
@@ -111,9 +111,22 @@
return kNetUnknown;
}
-bool GetServicePathType(DBusWrapperInterface* dbus_iface,
- const string& path,
- NetworkConnectionType* out_type) {
+NetworkTethering ParseTethering(const char* tethering_str) {
+ if (!strcmp(tethering_str, shill::kTetheringNotDetectedState)) {
+ return NetworkTethering::kNotDetected;
+ } else if (!strcmp(tethering_str, shill::kTetheringSuspectedState)) {
+ return NetworkTethering::kSuspected;
+ } else if (!strcmp(tethering_str, shill::kTetheringConfirmedState)) {
+ return NetworkTethering::kConfirmed;
+ }
+ LOG(WARNING) << "Unknown Tethering value: " << tethering_str;
+ return NetworkTethering::kUnknown;
+}
+
+bool GetServicePathProperties(DBusWrapperInterface* dbus_iface,
+ const string& path,
+ NetworkConnectionType* out_type,
+ NetworkTethering* out_tethering) {
GHashTable* hash_table = NULL;
TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
@@ -121,8 +134,23 @@
shill::kFlimflamServiceInterface,
&hash_table));
+ // Populate the out_tethering.
GValue* value = (GValue*)g_hash_table_lookup(hash_table,
- shill::kTypeProperty);
+ shill::kTetheringProperty);
+ const char* tethering_str = NULL;
+
+ if (value != NULL)
+ tethering_str = g_value_get_string(value);
+ if (tethering_str != NULL) {
+ *out_tethering = ParseTethering(tethering_str);
+ } else {
+ // Set to Unknown if not present.
+ *out_tethering = NetworkTethering::kUnknown;
+ }
+
+ // Populate the out_type property.
+ value = (GValue*)g_hash_table_lookup(hash_table,
+ shill::kTypeProperty);
const char* type_str = NULL;
bool success = false;
if (value != NULL && (type_str = g_value_get_string(value)) != NULL) {
@@ -151,7 +179,8 @@
ConnectionManager::ConnectionManager(SystemState *system_state)
: system_state_(system_state) {}
-bool ConnectionManager::IsUpdateAllowedOver(NetworkConnectionType type) const {
+bool ConnectionManager::IsUpdateAllowedOver(NetworkConnectionType type,
+ NetworkTethering tethering) const {
switch (type) {
case kNetBluetooth:
return false;
@@ -210,6 +239,12 @@
}
default:
+ if (tethering == NetworkTethering::kConfirmed) {
+ // Treat this connection as if it is a cellular connection.
+ LOG(INFO) << "Current connection is confirmed tethered, using Cellular "
+ "setting.";
+ return IsUpdateAllowedOver(kNetCellular, NetworkTethering::kUnknown);
+ }
return true;
}
}
@@ -227,15 +262,33 @@
return kValues[type];
}
-bool ConnectionManager::GetConnectionType(
+const char* ConnectionManager::StringForTethering(
+ NetworkTethering tethering) const {
+ switch (tethering) {
+ case NetworkTethering::kNotDetected:
+ return shill::kTetheringNotDetectedState;
+ case NetworkTethering::kSuspected:
+ return shill::kTetheringSuspectedState;
+ case NetworkTethering::kConfirmed:
+ return shill::kTetheringConfirmedState;
+ case NetworkTethering::kUnknown:
+ return "Unknown";
+ }
+ // The program shouldn't reach this point, but the compiler isn't smart
+ // enough to infer that.
+ return "Unknown";
+}
+
+bool ConnectionManager::GetConnectionProperties(
DBusWrapperInterface* dbus_iface,
- NetworkConnectionType* out_type) const {
+ NetworkConnectionType* out_type,
+ NetworkTethering* out_tethering) const {
string default_service_path;
TEST_AND_RETURN_FALSE(GetDefaultServicePath(dbus_iface,
&default_service_path));
- TEST_AND_RETURN_FALSE(GetServicePathType(dbus_iface,
- default_service_path,
- out_type));
+ TEST_AND_RETURN_FALSE(GetServicePathProperties(dbus_iface,
+ default_service_path,
+ out_type, out_tethering));
return true;
}
diff --git a/connection_manager.h b/connection_manager.h
index 58307ff..b50782b 100644
--- a/connection_manager.h
+++ b/connection_manager.h
@@ -20,6 +20,13 @@
kNetUnknown
};
+enum class NetworkTethering {
+ kNotDetected = 0,
+ kSuspected,
+ kConfirmed,
+ kUnknown
+};
+
class SystemState;
// This class exposes a generic interface to the connection manager
@@ -32,19 +39,27 @@
explicit ConnectionManager(SystemState* system_state);
// Populates |out_type| with the type of the network connection
- // that we are currently connected. The dbus_iface is used to
- // query the real connection manager (e.g shill).
- virtual bool GetConnectionType(DBusWrapperInterface* dbus_iface,
- NetworkConnectionType* out_type) const;
+ // that we are currently connected and |out_tethering| with the estimate of
+ // whether that network is being tethered. The dbus_iface is used to query
+ // the real connection manager (e.g shill).
+ virtual bool GetConnectionProperties(DBusWrapperInterface* dbus_iface,
+ NetworkConnectionType* out_type,
+ NetworkTethering* out_tethering) const;
// Returns true if we're allowed to update the system when we're
- // connected to the internet through the given network connection type.
- virtual bool IsUpdateAllowedOver(NetworkConnectionType type) const;
+ // connected to the internet through the given network connection type and the
+ // given tethering state.
+ virtual bool IsUpdateAllowedOver(NetworkConnectionType type,
+ NetworkTethering tethering) const;
// Returns the string representation corresponding to the given
// connection type.
virtual const char* StringForConnectionType(NetworkConnectionType type) const;
+ // Returns the string representation corresponding to the given tethering
+ // state.
+ virtual const char* StringForTethering(NetworkTethering tethering) const;
+
private:
// The global context for update_engine
SystemState* system_state_;
diff --git a/connection_manager_unittest.cc b/connection_manager_unittest.cc
index 3c89cb6..3dc065e 100644
--- a/connection_manager_unittest.cc
+++ b/connection_manager_unittest.cc
@@ -39,11 +39,15 @@
// PhysicalTechnology properties in the mocked service. If a NULL
// |physical_technology| is passed, the property is not set (not present).
void SetServiceReply(const char* service_type,
- const char* physical_technology);
+ const char* physical_technology,
+ const char* service_tethering);
void TestWithServiceType(
const char* service_type,
const char* physical_technology,
NetworkConnectionType expected_type);
+ void TestWithServiceTethering(
+ const char* service_tethering,
+ NetworkTethering expected_tethering);
static const char* kGetPropertiesMethod;
DBusGProxy* kMockFlimFlamManagerProxy_;
@@ -109,7 +113,8 @@
}
void ConnectionManagerTest::SetServiceReply(const char* service_type,
- const char* physical_technology) {
+ const char* physical_technology,
+ const char* service_tethering) {
// Initialize return value for D-Bus call to Service object.
// TODO (jaysri): Free the objects allocated here.
GHashTable* service_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
@@ -134,6 +139,17 @@
physical_technology_value);
}
+ if (service_tethering != NULL) {
+ GValue* service_tethering_value = g_new0(GValue, 1);
+ EXPECT_EQ(service_tethering_value,
+ g_value_init(service_tethering_value, G_TYPE_STRING));
+ g_value_set_static_string(service_tethering_value, service_tethering);
+
+ g_hash_table_insert(service_hash_table,
+ const_cast<char*>("Tethering"),
+ service_tethering_value);
+ }
+
// Plumb return value into mock object.
EXPECT_CALL(dbus_iface_, ProxyCall_0_1(kMockFlimFlamServiceProxy_,
StrEq(kGetPropertiesMethod),
@@ -159,13 +175,29 @@
SetupMocks("/service/guest-network");
SetManagerReply(kServicePath_, DBUS_TYPE_G_OBJECT_PATH_ARRAY);
- SetServiceReply(service_type, physical_technology);
+ SetServiceReply(service_type, physical_technology,
+ shill::kTetheringNotDetectedState);
NetworkConnectionType type;
- EXPECT_TRUE(cmut_.GetConnectionType(&dbus_iface_, &type));
+ NetworkTethering tethering;
+ EXPECT_TRUE(cmut_.GetConnectionProperties(&dbus_iface_, &type, &tethering));
EXPECT_EQ(expected_type, type);
}
+void ConnectionManagerTest::TestWithServiceTethering(
+ const char* service_tethering,
+ NetworkTethering expected_tethering) {
+
+ SetupMocks("/service/guest-network");
+ SetManagerReply(kServicePath_, DBUS_TYPE_G_OBJECT_PATH_ARRAY);
+ SetServiceReply(shill::kTypeWifi, NULL, service_tethering);
+
+ NetworkConnectionType type;
+ NetworkTethering tethering;
+ EXPECT_TRUE(cmut_.GetConnectionProperties(&dbus_iface_, &type, &tethering));
+ EXPECT_EQ(expected_tethering, tethering);
+}
+
TEST_F(ConnectionManagerTest, SimpleTest) {
TestWithServiceType(shill::kTypeEthernet, NULL, kNetEthernet);
TestWithServiceType(shill::kTypeWifi, NULL, kNetWifi);
@@ -181,6 +213,17 @@
TestWithServiceType(shill::kTypeVPN, shill::kTypeWimax, kNetWimax);
}
+TEST_F(ConnectionManagerTest, TetheringTest) {
+ TestWithServiceTethering(shill::kTetheringConfirmedState,
+ NetworkTethering::kConfirmed);
+ TestWithServiceTethering(shill::kTetheringNotDetectedState,
+ NetworkTethering::kNotDetected);
+ TestWithServiceTethering(shill::kTetheringSuspectedState,
+ NetworkTethering::kSuspected);
+ TestWithServiceTethering("I'm not a valid property value =)",
+ NetworkTethering::kUnknown);
+}
+
TEST_F(ConnectionManagerTest, UnknownTest) {
TestWithServiceType("foo", NULL, kNetUnknown);
}
@@ -189,22 +232,25 @@
EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
// Updates over Ethernet are allowed even if there's no policy.
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi, NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
@@ -222,15 +268,16 @@
.Times(1)
.WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
policy::MockDevicePolicy allow_3g_policy;
EXPECT_CALL(mock_system_state_, device_policy())
- .Times(1)
- .WillOnce(Return(&allow_3g_policy));
+ .Times(3)
+ .WillRepeatedly(Return(&allow_3g_policy));
// This test tests multiple connection types being allowed, with
// 3G one among them. Only Cellular is currently enforced by the policy
@@ -240,19 +287,42 @@
allowed_set.insert(cmut_.StringForConnectionType(kNetBluetooth));
EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
- .Times(1)
- .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
+ .Times(3)
+ .WillRepeatedly(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet,
+ NetworkTethering::kUnknown));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet,
+ NetworkTethering::kNotDetected));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi, NetworkTethering::kUnknown));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax, NetworkTethering::kUnknown));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth,
+ NetworkTethering::kUnknown));
+
+ // Tethered networks are treated in the same way as Cellular networks and
+ // thus allowed.
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet,
+ NetworkTethering::kConfirmed));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi,
+ NetworkTethering::kConfirmed));
}
TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
EXPECT_CALL(mock_system_state_, device_policy()).Times(1);
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
+}
+
+TEST_F(ConnectionManagerTest, BlockUpdatesOverTetheredNetworkByDefaultTest) {
+ EXPECT_CALL(mock_system_state_, device_policy()).Times(2);
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetWifi,
+ NetworkTethering::kConfirmed));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetEthernet,
+ NetworkTethering::kConfirmed));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi,
+ NetworkTethering::kSuspected));
}
TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
@@ -273,7 +343,8 @@
.Times(1)
.WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
@@ -293,7 +364,8 @@
.Times(1)
.WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(false)));
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
@@ -313,7 +385,8 @@
EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
.Times(1)
.WillOnce(Return(false));
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
// Allow per user pref.
EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
@@ -322,7 +395,8 @@
EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
.Times(1)
.WillOnce(DoAll(SetArgumentPointee<1>(true), Return(true)));
- EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
// Block per user pref.
EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
@@ -331,7 +405,8 @@
EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
.Times(1)
.WillOnce(DoAll(SetArgumentPointee<1>(false), Return(true)));
- EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
+ EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular,
+ NetworkTethering::kUnknown));
}
TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
@@ -358,7 +433,8 @@
SetManagerReply(&service_name, DBUS_TYPE_G_STRING_ARRAY);
NetworkConnectionType type;
- EXPECT_FALSE(cmut_.GetConnectionType(&dbus_iface_, &type));
+ NetworkTethering tethering;
+ EXPECT_FALSE(cmut_.GetConnectionProperties(&dbus_iface_, &type, &tethering));
}
} // namespace chromeos_update_engine
diff --git a/dbus_service.cc b/dbus_service.cc
index 5562f4e..a9455fe 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -440,7 +440,9 @@
// Return the current setting based on the same logic used while checking for
// updates. A log message could be printed as the result of this test.
LOG(INFO) << "Checking if updates over cellular networks are allowed:";
- *allowed = cm->IsUpdateAllowedOver(chromeos_update_engine::kNetCellular);
+ *allowed = cm->IsUpdateAllowedOver(
+ chromeos_update_engine::kNetCellular,
+ chromeos_update_engine::NetworkTethering::kUnknown);
return TRUE;
}
diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index 140bf81..82aef7f 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -431,9 +431,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
.WillRepeatedly(Return(shill::kTypeWifi));
@@ -460,9 +462,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
.WillRepeatedly(Return(shill::kTypeEthernet));
@@ -497,9 +501,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax))
.WillRepeatedly(Return(shill::kTypeWimax));
@@ -576,9 +582,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular))
.WillRepeatedly(Return(shill::kTypeCellular));
@@ -652,9 +660,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
delegate.fetcher_->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
.WillRepeatedly(Return(shill::kTypeWifi));
@@ -710,9 +720,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
.WillRepeatedly(Return(shill::kTypeWifi));
@@ -793,9 +805,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
.WillRepeatedly(Return(shill::kTypeEthernet));
@@ -827,9 +841,11 @@
// Don't allow connection to server by denying access over ethernet.
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet, _))
.WillRepeatedly(Return(false));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
.WillRepeatedly(Return(shill::kTypeEthernet));
@@ -896,9 +912,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
.WillRepeatedly(Return(shill::kTypeEthernet));
@@ -1014,9 +1032,11 @@
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher_in->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
.WillRepeatedly(Return(shill::kTypeWifi));
@@ -1212,9 +1232,11 @@
scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
fetcher->GetSystemState()->connection_manager());
- EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
- EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+ EXPECT_CALL(*mock_cm, GetConnectionProperties(_,_,_))
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi),
+ SetArgumentPointee<2>(NetworkTethering::kUnknown),
+ Return(true)));
+ EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi, _))
.WillRepeatedly(Return(is_allowed));
EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
.WillRepeatedly(Return(shill::kTypeWifi));
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index 41927ca..4667fe6 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -40,14 +40,16 @@
// On error, returns false.
bool LibcurlHttpFetcher::IsUpdateAllowedOverCurrentConnection() const {
NetworkConnectionType type;
+ NetworkTethering tethering;
RealDBusWrapper dbus_iface;
ConnectionManager* connection_manager = system_state_->connection_manager();
- if (!connection_manager->GetConnectionType(&dbus_iface, &type)) {
+ if (!connection_manager->GetConnectionProperties(&dbus_iface,
+ &type, &tethering)) {
LOG(INFO) << "We could not determine our connection type. "
<< "Defaulting to allow updates.";
return true;
}
- bool is_allowed = connection_manager->IsUpdateAllowedOver(type);
+ bool is_allowed = connection_manager->IsUpdateAllowedOver(type, tethering);
LOG(INFO) << "We are connected via "
<< connection_manager->StringForConnectionType(type)
<< ", Updates allowed: " << (is_allowed ? "Yes" : "No");
diff --git a/mock_connection_manager.h b/mock_connection_manager.h
index c74d6ad..71b3019 100644
--- a/mock_connection_manager.h
+++ b/mock_connection_manager.h
@@ -19,13 +19,19 @@
MockConnectionManager(SystemState* system_state)
: ConnectionManager(system_state) {}
- MOCK_CONST_METHOD2(GetConnectionType, bool(DBusWrapperInterface* dbus_iface,
- NetworkConnectionType* out_type));
+ MOCK_CONST_METHOD3(GetConnectionProperties,
+ bool(DBusWrapperInterface* dbus_iface,
+ NetworkConnectionType* out_type,
+ NetworkTethering* out_tethering));
- MOCK_CONST_METHOD1(IsUpdateAllowedOver, bool(NetworkConnectionType type));
+ MOCK_CONST_METHOD2(IsUpdateAllowedOver, bool(NetworkConnectionType type,
+ NetworkTethering tethering));
MOCK_CONST_METHOD1(StringForConnectionType,
const char*(NetworkConnectionType type));
+
+ MOCK_CONST_METHOD1(StringForTethering,
+ const char*(NetworkTethering tethering));
};
} // namespace chromeos_update_engine