Extracted WiFi interface from Network interface

BUG: 24111116

Change-Id: Idffd3b84d2b5b5b7fc6414511bbc6fb7aaca98d3
Reviewed-on: https://weave-review.googlesource.com/1113
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/libweave/examples/ubuntu/main.cc b/libweave/examples/ubuntu/main.cc
index 2a96ee2..b0b7f14 100644
--- a/libweave/examples/ubuntu/main.cc
+++ b/libweave/examples/ubuntu/main.cc
@@ -48,7 +48,7 @@
   opts.disable_security = false;
   opts.enable_ping = true;
   device->Start(opts, &config_store, &task_runner, &http_client, &network,
-                &mdns, &http_server, &bluetooth);
+                &mdns, &http_server, &network, &bluetooth);
 
   task_runner.Run();
 
diff --git a/libweave/examples/ubuntu/network_manager.h b/libweave/examples/ubuntu/network_manager.h
index 8abc80d..4855cfa 100644
--- a/libweave/examples/ubuntu/network_manager.h
+++ b/libweave/examples/ubuntu/network_manager.h
@@ -11,6 +11,7 @@
 #include <base/memory/weak_ptr.h>
 #include <base/time/time.h>
 #include <weave/network.h>
+#include <weave/wifi.h>
 
 namespace weave {
 
@@ -20,7 +21,7 @@
 
 // Basic weave::Network implementation.
 // Production version of SSL socket needs secure server certificate check.
-class NetworkImpl : public Network {
+class NetworkImpl : public Network, public Wifi {
  public:
   explicit NetworkImpl(TaskRunner* task_runner, bool force_bootstrapping);
   ~NetworkImpl();
diff --git a/libweave/include/weave/device.h b/libweave/include/weave/device.h
index c7ed3ae..e45d727 100644
--- a/libweave/include/weave/device.h
+++ b/libweave/include/weave/device.h
@@ -21,6 +21,7 @@
 #include <weave/privet.h>
 #include <weave/state.h>
 #include <weave/task_runner.h>
+#include <weave/wifi.h>
 
 namespace weave {
 
@@ -43,6 +44,7 @@
                      Network* network,
                      Mdns* mdns,
                      HttpServer* http_server,
+                     Wifi* wifi,
                      Bluetooth* bluetooth) = 0;
 
   virtual Commands* GetCommands() = 0;
diff --git a/libweave/include/weave/network.h b/libweave/include/weave/network.h
index 3ae70c0..1d4e07f 100644
--- a/libweave/include/weave/network.h
+++ b/libweave/include/weave/network.h
@@ -5,7 +5,6 @@
 #ifndef LIBWEAVE_INCLUDE_WEAVE_NETWORK_H_
 #define LIBWEAVE_INCLUDE_WEAVE_NETWORK_H_
 
-#include <map>
 #include <string>
 
 #include <base/callback.h>
@@ -31,22 +30,9 @@
   virtual void AddOnConnectionChangedCallback(
       const OnConnectionChangedCallback& listener) = 0;
 
-  // Implementation should attempt to connect to the given network with the
-  // given passphrase. This is accomplished by:
-  // Returns false on immediate failures with some descriptive codes in |error|.
-  virtual bool ConnectToService(const std::string& ssid,
-                                const std::string& passphrase,
-                                const base::Closure& on_success,
-                                ErrorPtr* error) = 0;
-
+  // Returns current Internet connectivity state
   virtual NetworkState GetConnectionState() const = 0;
 
-  // Starts WiFi access point for wifi setup.
-  virtual void EnableAccessPoint(const std::string& ssid) = 0;
-
-  // Stops WiFi access point.
-  virtual void DisableAccessPoint() = 0;
-
   // Opens bidirectional sockets and returns attached stream.
   virtual void OpenSslSocket(
       const std::string& host,
diff --git a/libweave/include/weave/test/mock_network.h b/libweave/include/weave/test/mock_network.h
index f188223..e2d0074 100644
--- a/libweave/include/weave/test/mock_network.h
+++ b/libweave/include/weave/test/mock_network.h
@@ -21,15 +21,7 @@
 
   MOCK_METHOD1(AddOnConnectionChangedCallback,
                void(const OnConnectionChangedCallback&));
-  MOCK_METHOD4(ConnectToService,
-               bool(const std::string&,
-                    const std::string&,
-                    const base::Closure&,
-                    ErrorPtr*));
   MOCK_CONST_METHOD0(GetConnectionState, NetworkState());
-  MOCK_METHOD1(EnableAccessPoint, void(const std::string&));
-  MOCK_METHOD0(DisableAccessPoint, void());
-
   MOCK_METHOD4(OpenSslSocket,
                void(const std::string&,
                     uint16_t,
diff --git a/libweave/include/weave/test/mock_wifi.h b/libweave/include/weave/test/mock_wifi.h
new file mode 100644
index 0000000..b32d1f2
--- /dev/null
+++ b/libweave/include/weave/test/mock_wifi.h
@@ -0,0 +1,34 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIBWEAVE_INCLUDE_WEAVE_TEST_MOCK_WIFI_H_
+#define LIBWEAVE_INCLUDE_WEAVE_TEST_MOCK_WIFI_H_
+
+#include <weave/network.h>
+
+#include <string>
+
+#include <gmock/gmock.h>
+
+namespace weave {
+namespace test {
+
+class MockWifi : public Wifi {
+ public:
+  MockWifi() {}
+  ~MockWifi() override = default;
+
+  MOCK_METHOD4(ConnectToService,
+               bool(const std::string&,
+                    const std::string&,
+                    const base::Closure&,
+                    ErrorPtr*));
+  MOCK_METHOD1(EnableAccessPoint, void(const std::string&));
+  MOCK_METHOD0(DisableAccessPoint, void());
+};
+
+}  // namespace test
+}  // namespace weave
+
+#endif  // LIBWEAVE_INCLUDE_WEAVE_TEST_MOCK_WIFI_H_
diff --git a/libweave/include/weave/wifi.h b/libweave/include/weave/wifi.h
new file mode 100644
index 0000000..95edbeb
--- /dev/null
+++ b/libweave/include/weave/wifi.h
@@ -0,0 +1,37 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIBWEAVE_INCLUDE_WEAVE_WIFI_H_
+#define LIBWEAVE_INCLUDE_WEAVE_WIFI_H_
+
+#include <string>
+
+#include <base/callback.h>
+#include <weave/error.h>
+
+namespace weave {
+
+class Wifi {
+ public:
+  // Implementation should attempt to connect to the given network with the
+  // given passphrase. Implementation should run either of callback.
+  // Callback should be posted.
+  virtual bool ConnectToService(const std::string& ssid,
+                                const std::string& passphrase,
+                                const base::Closure& success_callback,
+                                ErrorPtr* error) = 0;
+
+  // Starts WiFi access point for wifi setup.
+  virtual void EnableAccessPoint(const std::string& ssid) = 0;
+
+  // Stops WiFi access point.
+  virtual void DisableAccessPoint() = 0;
+
+ protected:
+  virtual ~Wifi() = default;
+};
+
+}  // namespace weave
+
+#endif  // LIBWEAVE_INCLUDE_WEAVE_WIFI_H_
diff --git a/libweave/src/device_manager.cc b/libweave/src/device_manager.cc
index 1435aeb..111b87e 100644
--- a/libweave/src/device_manager.cc
+++ b/libweave/src/device_manager.cc
@@ -36,6 +36,7 @@
                           Network* network,
                           Mdns* mdns,
                           HttpServer* http_server,
+                          Wifi* wifi,
                           Bluetooth* bluetooth) {
   command_manager_ = std::make_shared<CommandManager>();
   command_manager_->Startup(config_store);
@@ -57,7 +58,8 @@
   device_info_->Start();
 
   if (!options.disable_privet) {
-    StartPrivet(options, task_runner, network, mdns, http_server, bluetooth);
+    StartPrivet(options, task_runner, network, mdns, http_server, wifi,
+                bluetooth);
   } else {
     CHECK(!http_server);
     CHECK(!mdns);
@@ -89,9 +91,10 @@
                                 Network* network,
                                 Mdns* mdns,
                                 HttpServer* http_server,
+                                Wifi* wifi,
                                 Bluetooth* bluetooth) {
   privet_.reset(new privet::Manager{});
-  privet_->Start(options, task_runner, network, mdns, http_server,
+  privet_->Start(options, task_runner, network, mdns, http_server, wifi,
                  device_info_.get(), command_manager_.get(),
                  state_manager_.get());
 
diff --git a/libweave/src/device_manager.h b/libweave/src/device_manager.h
index 376f122..bc6f031 100644
--- a/libweave/src/device_manager.h
+++ b/libweave/src/device_manager.h
@@ -33,6 +33,7 @@
              Network* network,
              Mdns* mdns,
              HttpServer* http_server,
+             Wifi* wifi,
              Bluetooth* bluetooth) override;
 
   Commands* GetCommands() override;
@@ -48,6 +49,7 @@
                    Network* network,
                    Mdns* mdns,
                    HttpServer* http_server,
+                   Wifi* wifi,
                    Bluetooth* bluetooth);
 
   void OnWiFiBootstrapStateChanged(weave::WifiSetupState state);
diff --git a/libweave/src/privet/privet_manager.cc b/libweave/src/privet/privet_manager.cc
index 2c581f7..4363d5a 100644
--- a/libweave/src/privet/privet_manager.cc
+++ b/libweave/src/privet/privet_manager.cc
@@ -40,6 +40,7 @@
                     Network* network,
                     Mdns* mdns,
                     HttpServer* http_server,
+                    Wifi* wifi,
                     DeviceRegistrationInfo* device,
                     CommandManager* command_manager,
                     StateManager* state_manager) {
@@ -55,11 +56,11 @@
   network->AddOnConnectionChangedCallback(
       base::Bind(&Manager::OnConnectivityChanged, base::Unretained(this)));
 
-  if (device->GetSettings().wifi_auto_setup_enabled) {
+  if (wifi && device->GetSettings().wifi_auto_setup_enabled) {
     VLOG(1) << "Enabling WiFi bootstrapping.";
     wifi_bootstrap_manager_.reset(new WifiBootstrapManager(
         device->GetSettings().last_configured_ssid, options.test_privet_ssid,
-        device->GetSettings().ble_setup_enabled, task_runner, network,
+        device->GetSettings().ble_setup_enabled, task_runner, network, wifi,
         cloud_.get()));
     wifi_bootstrap_manager_->Init();
   }
diff --git a/libweave/src/privet/privet_manager.h b/libweave/src/privet/privet_manager.h
index cc9ccc5..50f7416 100644
--- a/libweave/src/privet/privet_manager.h
+++ b/libweave/src/privet/privet_manager.h
@@ -52,6 +52,7 @@
              Network* network,
              Mdns* mdns,
              HttpServer* http_server,
+             Wifi* wifi,
              DeviceRegistrationInfo* device,
              CommandManager* command_manager,
              StateManager* state_manager);
diff --git a/libweave/src/privet/wifi_bootstrap_manager.cc b/libweave/src/privet/wifi_bootstrap_manager.cc
index dc5ef7f..b9766d9 100644
--- a/libweave/src/privet/wifi_bootstrap_manager.cc
+++ b/libweave/src/privet/wifi_bootstrap_manager.cc
@@ -9,6 +9,7 @@
 #include <weave/enum_to_string.h>
 #include <weave/network.h>
 #include <weave/task_runner.h>
+#include <weave/wifi.h>
 
 #include "libweave/src/bind_lambda.h"
 #include "libweave/src/privet/constants.h"
@@ -22,13 +23,18 @@
     bool ble_setup_enabled,
     TaskRunner* task_runner,
     Network* network,
+    Wifi* wifi,
     CloudDelegate* gcd)
     : task_runner_{task_runner},
       network_{network},
+      wifi_{wifi},
       ssid_generator_{gcd, this},
       last_configured_ssid_{last_configured_ssid},
       test_privet_ssid_{test_privet_ssid},
       ble_setup_enabled_{ble_setup_enabled} {
+  CHECK(network_);
+  CHECK(task_runner_);
+  CHECK(wifi_);
 }
 
 void WifiBootstrapManager::Init() {
@@ -74,13 +80,13 @@
   // TODO(vitalybuka): Add SSID probing.
   privet_ssid_ = GenerateSsid();
   CHECK(!privet_ssid_.empty());
-  network_->EnableAccessPoint(privet_ssid_);
+  wifi_->EnableAccessPoint(privet_ssid_);
   LOG_IF(INFO, ble_setup_enabled_) << "BLE Bootstrap start: not implemented.";
 }
 
 void WifiBootstrapManager::EndBootstrapping() {
   LOG_IF(INFO, ble_setup_enabled_) << "BLE Bootstrap stop: not implemented.";
-  network_->DisableAccessPoint();
+  wifi_->DisableAccessPoint();
   privet_ssid_.clear();
 }
 
@@ -93,10 +99,10 @@
       FROM_HERE, base::Bind(&WifiBootstrapManager::OnConnectTimeout,
                             tasks_weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMinutes(3));
-  network_->ConnectToService(ssid, passphrase,
-                             base::Bind(&WifiBootstrapManager::OnConnectSuccess,
-                                        tasks_weak_factory_.GetWeakPtr(), ssid),
-                             nullptr);
+  wifi_->ConnectToService(ssid, passphrase,
+                          base::Bind(&WifiBootstrapManager::OnConnectSuccess,
+                                     tasks_weak_factory_.GetWeakPtr(), ssid),
+                          nullptr);
 }
 
 void WifiBootstrapManager::EndConnecting() {
diff --git a/libweave/src/privet/wifi_bootstrap_manager.h b/libweave/src/privet/wifi_bootstrap_manager.h
index 65436c2..340296c 100644
--- a/libweave/src/privet/wifi_bootstrap_manager.h
+++ b/libweave/src/privet/wifi_bootstrap_manager.h
@@ -24,6 +24,7 @@
 
 class Network;
 class TaskRunner;
+class Wifi;
 
 namespace privet {
 
@@ -41,6 +42,7 @@
                        bool wifi_setup_enabled,
                        TaskRunner* task_runner,
                        Network* shill_client,
+                       Wifi* wifi,
                        CloudDelegate* gcd);
   ~WifiBootstrapManager() override = default;
   virtual void Init();
@@ -96,6 +98,7 @@
   ConnectionState connection_state_{ConnectionState::kDisabled};
   TaskRunner* task_runner_{nullptr};
   Network* network_{nullptr};
+  Wifi* wifi_{nullptr};
   WifiSsidGenerator ssid_generator_;
   base::Time monitor_until_;
 
diff --git a/libweave/src/weave_unittest.cc b/libweave/src/weave_unittest.cc
index d6418c3..43a7282 100644
--- a/libweave/src/weave_unittest.cc
+++ b/libweave/src/weave_unittest.cc
@@ -13,6 +13,7 @@
 #include <weave/test/mock_mdns.h>
 #include <weave/test/mock_network.h>
 #include <weave/test/mock_task_runner.h>
+#include <weave/test/mock_wifi.h>
 #include <weave/test/unittest_utils.h>
 
 #include "libweave/src/bind_lambda.h"
@@ -282,7 +283,7 @@
   void InitDefaultExpectations() {
     InitConfigStore();
     InitNetwork();
-    EXPECT_CALL(network_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
+    EXPECT_CALL(wifi_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
         .WillOnce(Return());
     InitHttpServer();
     InitMdns();
@@ -293,7 +294,7 @@
     options.xmpp_enabled = false;
 
     device_->Start(options, &config_store_, &task_runner_, &http_client_,
-                   &network_, &mdns_, &http_server_, &bluetooth_);
+                   &network_, &mdns_, &http_server_, &wifi_, &bluetooth_);
 
     cloud_ = device_->GetCloud();
     ASSERT_TRUE(cloud_);
@@ -327,6 +328,7 @@
   StrictMock<test::MockNetwork> network_;
   StrictMock<test::MockMdns> mdns_;
   StrictMock<test::MockHttpServer> http_server_;
+  StrictMock<test::MockWifi> wifi_;
   StrictMock<test::MockBluetooth> bluetooth_;
 
   std::vector<Network::OnConnectionChangedCallback> network_callbacks_;
@@ -348,7 +350,24 @@
 
   InitConfigStore();
   device_->Start(options, &config_store_, &task_runner_, &http_client_,
-                 &network_, nullptr, nullptr, nullptr);
+                 &network_, nullptr, nullptr, &wifi_, nullptr);
+}
+
+TEST_F(WeaveTest, StartNoWifi) {
+  InitConfigStore();
+  InitNetwork();
+  InitHttpServer();
+  InitMdns();
+  InitMdnsPublishing(false, "CB");
+
+  weave::Device::Options options;
+  device_->Start(options, &config_store_, &task_runner_, &http_client_,
+                 &network_, &mdns_, &http_server_, nullptr, &bluetooth_);
+
+  for (const auto& cb : http_server_changed_cb_)
+    cb.Run(http_server_);
+
+  task_runner_.Run();
 }
 
 class WeaveBasicTest : public WeaveTest {
@@ -420,7 +439,7 @@
   // Long disconnect.
   NotifyNetworkChanged(NetworkState::kOffline, {});
   auto offline_from = task_runner_.GetClock()->Now();
-  EXPECT_CALL(network_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
+  EXPECT_CALL(wifi_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
       .WillOnce(InvokeWithoutArgs([this, offline_from]() {
         EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                   base::TimeDelta::FromMinutes(1));
@@ -442,7 +461,7 @@
   for (int i = 0; i < 5; ++i) {
     auto offline_from = task_runner_.GetClock()->Now();
     // Temporarily offline mode.
-    EXPECT_CALL(network_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
+    EXPECT_CALL(wifi_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
         .WillOnce(InvokeWithoutArgs([this, &offline_from]() {
           EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                     base::TimeDelta::FromMinutes(1));
@@ -452,7 +471,7 @@
 
     // Try to reconnect again.
     offline_from = task_runner_.GetClock()->Now();
-    EXPECT_CALL(network_, DisableAccessPoint())
+    EXPECT_CALL(wifi_, DisableAccessPoint())
         .WillOnce(InvokeWithoutArgs([this, offline_from]() {
           EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                     base::TimeDelta::FromMinutes(5));
@@ -472,7 +491,7 @@
       .WillRepeatedly(Return(NetworkState::kOffline));
 
   auto offline_from = task_runner_.GetClock()->Now();
-  EXPECT_CALL(network_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
+  EXPECT_CALL(wifi_, EnableAccessPoint(MatchesRegex("DEVICE_NAME.*prv")))
       .WillOnce(InvokeWithoutArgs([this, &offline_from]() {
         EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                   base::TimeDelta::FromMinutes(1));