Changed ConnectToService to accept error callback

Method is async and can return error with delay.

BUG: 24267885
Change-Id: I5a8d15d2cc7872bee4e54033bac36f1b839c5559
Reviewed-on: https://weave-review.googlesource.com/1114
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/libweave/examples/ubuntu/network_manager.cc b/libweave/examples/ubuntu/network_manager.cc
index 2f96c09..6217f25 100644
--- a/libweave/examples/ubuntu/network_manager.cc
+++ b/libweave/examples/ubuntu/network_manager.cc
@@ -202,11 +202,13 @@
   callbacks_.push_back(listener);
 }
 
-void NetworkImpl::TryToConnect(const std::string& ssid,
-                               const std::string& passphrase,
-                               int pid,
-                               base::Time until,
-                               const base::Closure& on_success) {
+void NetworkImpl::TryToConnect(
+    const std::string& ssid,
+    const std::string& passphrase,
+    int pid,
+    base::Time until,
+    const base::Closure& success_callback,
+    const base::Callback<void(const Error*)>& error_callback) {
   if (pid) {
     int status = 0;
     if (pid == waitpid(pid, &status, WNOWAIT)) {
@@ -223,7 +225,7 @@
       close(sockf_d);
 
       if (ssid == essid)
-        return task_runner_->PostDelayedTask(FROM_HERE, on_success, {});
+        return task_runner_->PostDelayedTask(FROM_HERE, success_callback, {});
       pid = 0;  // Try again.
     }
   }
@@ -233,29 +235,42 @@
                   {"dev", "wifi", "connect", ssid, "password", passphrase});
   }
 
-  if (base::Time::Now() >= until)
+  if (base::Time::Now() >= until) {
+    ErrorPtr error;
+    Error::AddTo(&error, FROM_HERE, "wifi", "timeout",
+                 "Timeout connecting to WiFI network.");
+    task_runner_->PostDelayedTask(
+        FROM_HERE, base::Bind(error_callback, base::Owned(error.release())),
+        {});
     return;
+  }
 
   task_runner_->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&NetworkImpl::TryToConnect, weak_ptr_factory_.GetWeakPtr(),
-                 ssid, passphrase, pid, until, on_success),
+      FROM_HERE, base::Bind(&NetworkImpl::TryToConnect,
+                            weak_ptr_factory_.GetWeakPtr(), ssid, passphrase,
+                            pid, until, success_callback, error_callback),
       base::TimeDelta::FromSeconds(1));
 }
 
-bool NetworkImpl::ConnectToService(const std::string& ssid,
-                                   const std::string& passphrase,
-                                   const base::Closure& on_success,
-                                   ErrorPtr* error) {
+void NetworkImpl::ConnectToService(
+    const std::string& ssid,
+    const std::string& passphrase,
+    const base::Closure& success_callback,
+    const base::Callback<void(const Error*)>& error_callback) {
   force_bootstrapping_ = false;
   CHECK(!hostapd_started_);
   if (hostapd_started_) {
-    Error::AddTo(error, FROM_HERE, "wifi", "busy", "Running Access Point.");
-    return false;
+    ErrorPtr error;
+    Error::AddTo(&error, FROM_HERE, "wifi", "busy", "Running Access Point.");
+    task_runner_->PostDelayedTask(
+        FROM_HERE, base::Bind(error_callback, base::Owned(error.release())),
+        {});
+    return;
   }
 
   TryToConnect(ssid, passphrase, 0,
-               base::Time::Now() + base::TimeDelta::FromMinutes(1), on_success);
+               base::Time::Now() + base::TimeDelta::FromMinutes(1),
+               success_callback, error_callback);
 }
 
 void NetworkImpl::UpdateNetworkState() {
diff --git a/libweave/examples/ubuntu/network_manager.h b/libweave/examples/ubuntu/network_manager.h
index 4855cfa..c7f2480 100644
--- a/libweave/examples/ubuntu/network_manager.h
+++ b/libweave/examples/ubuntu/network_manager.h
@@ -26,27 +26,32 @@
   explicit NetworkImpl(TaskRunner* task_runner, bool force_bootstrapping);
   ~NetworkImpl();
 
+  // Network implementation
   void AddOnConnectionChangedCallback(
       const OnConnectionChangedCallback& listener) override;
-  bool ConnectToService(const std::string& ssid,
-                        const std::string& passphrase,
-                        const base::Closure& on_success,
-                        ErrorPtr* error) override;
   NetworkState GetConnectionState() const override;
-  void EnableAccessPoint(const std::string& ssid) override;
-  void DisableAccessPoint() override;
   void OpenSslSocket(
       const std::string& host,
       uint16_t port,
       const base::Callback<void(std::unique_ptr<Stream>)>& success_callback,
       const base::Callback<void(const Error*)>& error_callback) override;
 
+  // Wifi implementation
+  void ConnectToService(
+      const std::string& ssid,
+      const std::string& passphrase,
+      const base::Closure& success_callback,
+      const base::Callback<void(const Error*)>& error_callback) override;
+  void EnableAccessPoint(const std::string& ssid) override;
+  void DisableAccessPoint() override;
+
  private:
   void TryToConnect(const std::string& ssid,
                     const std::string& passphrase,
                     int pid,
                     base::Time until,
-                    const base::Closure& on_success);
+                    const base::Closure& success_callback,
+                    const base::Callback<void(const Error*)>& error_callback);
   void UpdateNetworkState();
 
   bool force_bootstrapping_{false};
diff --git a/libweave/include/weave/test/mock_wifi.h b/libweave/include/weave/test/mock_wifi.h
index b32d1f2..20223ed 100644
--- a/libweave/include/weave/test/mock_wifi.h
+++ b/libweave/include/weave/test/mock_wifi.h
@@ -20,10 +20,10 @@
   ~MockWifi() override = default;
 
   MOCK_METHOD4(ConnectToService,
-               bool(const std::string&,
+               void(const std::string&,
                     const std::string&,
                     const base::Closure&,
-                    ErrorPtr*));
+                    const base::Callback<void(const Error*)>&));
   MOCK_METHOD1(EnableAccessPoint, void(const std::string&));
   MOCK_METHOD0(DisableAccessPoint, void());
 };
diff --git a/libweave/include/weave/wifi.h b/libweave/include/weave/wifi.h
index 95edbeb..e763afa 100644
--- a/libweave/include/weave/wifi.h
+++ b/libweave/include/weave/wifi.h
@@ -17,10 +17,11 @@
   // 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;
+  virtual void ConnectToService(
+      const std::string& ssid,
+      const std::string& passphrase,
+      const base::Closure& success_callback,
+      const base::Callback<void(const Error*)>& error_callback) = 0;
 
   // Starts WiFi access point for wifi setup.
   virtual void EnableAccessPoint(const std::string& ssid) = 0;
diff --git a/libweave/src/privet/wifi_bootstrap_manager.cc b/libweave/src/privet/wifi_bootstrap_manager.cc
index b9766d9..dc076b5 100644
--- a/libweave/src/privet/wifi_bootstrap_manager.cc
+++ b/libweave/src/privet/wifi_bootstrap_manager.cc
@@ -96,13 +96,22 @@
           << ", pass=" << passphrase << ").";
   UpdateState(State::kConnecting);
   task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&WifiBootstrapManager::OnConnectTimeout,
-                            tasks_weak_factory_.GetWeakPtr()),
+      FROM_HERE, base::Bind(&WifiBootstrapManager::OnConnectError,
+                            tasks_weak_factory_.GetWeakPtr(), nullptr),
       base::TimeDelta::FromMinutes(3));
   wifi_->ConnectToService(ssid, passphrase,
                           base::Bind(&WifiBootstrapManager::OnConnectSuccess,
                                      tasks_weak_factory_.GetWeakPtr(), ssid),
-                          nullptr);
+                          base::Bind(&WifiBootstrapManager::OnConnectError,
+                                     tasks_weak_factory_.GetWeakPtr()));
+}
+
+void WifiBootstrapManager::OnConnectError(const Error* error) {
+  ErrorPtr new_error = error ? error->Clone() : nullptr;
+  Error::AddTo(&new_error, FROM_HERE, errors::kDomain, errors::kInvalidState,
+               "Failed to connect to provided network");
+  setup_state_ = SetupState{std::move(new_error)};
+  StartBootstrapping();
 }
 
 void WifiBootstrapManager::EndConnecting() {
@@ -224,15 +233,6 @@
   StartMonitoring();
 }
 
-void WifiBootstrapManager::OnConnectTimeout() {
-  VLOG(1) << "Wifi timed out while connecting";
-  ErrorPtr error;
-  Error::AddTo(&error, FROM_HERE, errors::kDomain, errors::kInvalidState,
-               "Failed to connect to provided network");
-  setup_state_ = SetupState{std::move(error)};
-  StartBootstrapping();
-}
-
 void WifiBootstrapManager::OnConnectivityChange() {
   VLOG(3) << "ConnectivityChanged: "
           << EnumToString(network_->GetConnectionState());
diff --git a/libweave/src/privet/wifi_bootstrap_manager.h b/libweave/src/privet/wifi_bootstrap_manager.h
index 340296c..6c091cd 100644
--- a/libweave/src/privet/wifi_bootstrap_manager.h
+++ b/libweave/src/privet/wifi_bootstrap_manager.h
@@ -85,8 +85,8 @@
   // to return to monitoring mode periodically in case our connectivity issues
   // were temporary.
   void OnBootstrapTimeout();
-  void OnConnectTimeout();
   void OnConnectSuccess(const std::string& ssid);
+  void OnConnectError(const Error* error);
   void OnConnectivityChange();
   void OnMonitorTimeout();
   void UpdateConnectionState();