shill: vpn: Don't auto-connect to a VPN service that has never connected.
This improves the chances that the VPN service is connectable.
BUG=chromium-os:38193
TEST=unit test
Change-Id: I5d505604aaa3fd30cb89c2a87de398544d5a1c27
Reviewed-on: https://gerrit.chromium.org/gerrit/41927
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Reviewed-by: Philipp Neubeck <pneubeck@chromium.org>
Tested-by: Philipp Neubeck <pneubeck@chromium.org>
Commit-Queue: Darin Petkov <petkov@chromium.org>
diff --git a/vpn_service.cc b/vpn_service.cc
index 39abd94..a7991e3 100644
--- a/vpn_service.cc
+++ b/vpn_service.cc
@@ -23,6 +23,8 @@
namespace shill {
+const char VPNService::kAutoConnNeverConnected[] = "never connected";
+
VPNService::VPNService(ControlInterface *control,
EventDispatcher *dispatcher,
Metrics *metrics,
@@ -141,4 +143,17 @@
Service::SetConnection(connection);
}
+bool VPNService::IsAutoConnectable(const char **reason) const {
+ if (!Service::IsAutoConnectable(reason)) {
+ return false;
+ }
+ // Don't auto-connect VPN services that have never connected. This improves
+ // the chances that the VPN service is connectable and avoids dialog popups.
+ if (!has_ever_connected()) {
+ *reason = kAutoConnNeverConnected;
+ return false;
+ }
+ return true;
+}
+
} // namespace shill
diff --git a/vpn_service.h b/vpn_service.h
index 1162e57..4a6bc9b 100644
--- a/vpn_service.h
+++ b/vpn_service.h
@@ -43,10 +43,17 @@
Error *error);
void set_storage_id(const std::string &id) { storage_id_ = id; }
+ protected:
+ // Inherited from Service.
+ virtual bool IsAutoConnectable(const char **reason) const;
+
private:
FRIEND_TEST(VPNServiceTest, GetDeviceRpcId);
+ FRIEND_TEST(VPNServiceTest, IsAutoConnectable);
FRIEND_TEST(VPNServiceTest, SetConnection);
+ static const char kAutoConnNeverConnected[];
+
virtual std::string GetDeviceRpcId(Error *error);
std::string storage_id_;
diff --git a/vpn_service_unittest.cc b/vpn_service_unittest.cc
index 645f67d..a7076d6 100644
--- a/vpn_service_unittest.cc
+++ b/vpn_service_unittest.cc
@@ -59,6 +59,14 @@
service_->state_ = state;
}
+ void SetHasEverConnected(bool connected) {
+ service_->has_ever_connected_ = connected;
+ }
+
+ void SetConnectable(bool connectable) {
+ service_->connectable_ = connectable;
+ }
+
std::string interface_name_;
std::string ipconfig_rpc_identifier_;
MockVPNDriver *driver_; // Owned by |service_|.
@@ -211,4 +219,21 @@
connection_->OnLowerDisconnect();
}
+TEST_F(VPNServiceTest, IsAutoConnectable) {
+ EXPECT_TRUE(service_->connectable());
+ EXPECT_FALSE(service_->has_ever_connected());
+
+ const char *reason = NULL;
+ EXPECT_FALSE(service_->IsAutoConnectable(&reason));
+ EXPECT_STREQ(VPNService::kAutoConnNeverConnected, reason);
+
+ SetHasEverConnected(true);
+ reason = NULL;
+ EXPECT_TRUE(service_->IsAutoConnectable(&reason));
+ EXPECT_FALSE(reason);
+
+ SetConnectable(false);
+ EXPECT_FALSE(service_->IsAutoConnectable(&reason));
+}
+
} // namespace shill