Split share discovery into two steps
This change modifies the current GetSharesInNetwork function so that a
callback is fired as soon a discovery is done to indicate that name
resolution is possible. Additionally, a new ShareFinder::DiscoveryHosts
method enables performing host discovery without querying each host for
its shares. This change will make it possible to perform name resolution
on reboot.
Bug: chromium:757625
Change-Id: I437ca8ad6400824a3fbc9b870b5fb0307cee2ac4
Reviewed-on: https://chromium-review.googlesource.com/1199685
Commit-Queue: Bailey Berro <baileyberro@chromium.org>
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589711}
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index ad07a030..52d463b 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -113,8 +113,15 @@
CallMount(options, share_path, username, password, std::move(callback));
}
-void SmbService::GatherSharesInNetwork(GatherSharesResponse callback) {
- share_finder_->GatherSharesInNetwork(std::move(callback));
+void SmbService::GatherSharesInNetwork(GatherSharesResponse shares_callback) {
+ share_finder_->GatherSharesInNetwork(base::DoNothing(),
+ std::move(shares_callback));
+}
+
+void SmbService::GatherSharesInNetwork(HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback) {
+ share_finder_->GatherSharesInNetwork(std::move(discovery_callback),
+ std::move(shares_callback));
}
void SmbService::CallMount(const file_system_provider::MountOptions& options,
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h
index eab3d9b..a4523dd 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.h
+++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -72,9 +72,12 @@
int32_t mount_id);
// Gathers the hosts in the network using |share_finder_| and gets the shares
- // for each of the hosts found. |callback| will be called once per host and
- // will contain the URLs to the shares found.
- void GatherSharesInNetwork(GatherSharesResponse callback);
+ // for each of the hosts found. |discovery_callback| is called as soon as host
+ // discovery is complete. |shares_callback| is called once per host and will
+ // contain the URLs to the shares found.
+ void GatherSharesInNetwork(GatherSharesResponse shares_callback);
+ void GatherSharesInNetwork(HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback);
private:
// Calls SmbProviderClient::Mount(). |temp_file_manager_| must be initialized
diff --git a/chrome/browser/chromeos/smb_client/smb_share_finder.cc b/chrome/browser/chromeos/smb_client/smb_share_finder.cc
index 6a3a4e6..8b2196d 100644
--- a/chrome/browser/chromeos/smb_client/smb_share_finder.cc
+++ b/chrome/browser/chromeos/smb_client/smb_share_finder.cc
@@ -16,9 +16,19 @@
SmbShareFinder::SmbShareFinder(SmbProviderClient* client) : client_(client) {}
SmbShareFinder::~SmbShareFinder() = default;
-void SmbShareFinder::GatherSharesInNetwork(GatherSharesResponse callback) {
- scanner_.FindHostsInNetwork(base::BindOnce(&SmbShareFinder::OnHostsFound,
- AsWeakPtr(), std::move(callback)));
+void SmbShareFinder::GatherSharesInNetwork(
+ HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback) {
+ scanner_.FindHostsInNetwork(base::BindOnce(
+ &SmbShareFinder::OnHostsFound, AsWeakPtr(), std::move(discovery_callback),
+ std::move(shares_callback)));
+}
+
+void SmbShareFinder::DiscoverHostsInNetwork(
+ HostDiscoveryResponse discovery_callback) {
+ scanner_.FindHostsInNetwork(base::BindOnce(&SmbShareFinder::OnHostsDiscovered,
+ AsWeakPtr(),
+ std::move(discovery_callback)));
}
void SmbShareFinder::RegisterHostLocator(std::unique_ptr<HostLocator> locator) {
@@ -36,17 +46,25 @@
return url.ReplaceHost(ip_address);
}
-void SmbShareFinder::OnHostsFound(GatherSharesResponse callback,
+void SmbShareFinder::OnHostsDiscovered(HostDiscoveryResponse discovery_callback,
+ bool success,
+ const HostMap& hosts) {
+ std::move(discovery_callback).Run();
+}
+
+void SmbShareFinder::OnHostsFound(HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback,
bool success,
const HostMap& hosts) {
+ std::move(discovery_callback).Run();
if (!success) {
LOG(ERROR) << "SmbShareFinder failed to find hosts";
- callback.Run(std::vector<SmbUrl>());
+ shares_callback.Run(std::vector<SmbUrl>());
return;
}
if (hosts.empty()) {
- callback.Run(std::vector<SmbUrl>());
+ shares_callback.Run(std::vector<SmbUrl>());
return;
}
@@ -57,18 +75,18 @@
client_->GetShares(
server_url, base::BindOnce(&SmbShareFinder::OnSharesFound, AsWeakPtr(),
- host_name, callback));
+ host_name, shares_callback));
}
}
void SmbShareFinder::OnSharesFound(
const std::string& host_name,
- GatherSharesResponse callback,
+ GatherSharesResponse shares_callback,
smbprovider::ErrorType error,
const smbprovider::DirectoryEntryListProto& entries) {
if (error != smbprovider::ErrorType::ERROR_OK) {
LOG(ERROR) << "Error finding shares: " << error;
- callback.Run(std::vector<SmbUrl>());
+ shares_callback.Run(std::vector<SmbUrl>());
return;
}
@@ -82,7 +100,7 @@
}
}
- callback.Run(shares);
+ shares_callback.Run(shares);
}
} // namespace smb_client
diff --git a/chrome/browser/chromeos/smb_client/smb_share_finder.h b/chrome/browser/chromeos/smb_client/smb_share_finder.h
index 3cb8aa5..321be7e 100644
--- a/chrome/browser/chromeos/smb_client/smb_share_finder.h
+++ b/chrome/browser/chromeos/smb_client/smb_share_finder.h
@@ -23,6 +23,9 @@
using GatherSharesResponse =
base::RepeatingCallback<void(const std::vector<SmbUrl>& shares_gathered)>;
+// The callback run to indicate the scan for hosts on the network is complete.
+using HostDiscoveryResponse = base::OnceClosure;
+
// This class is responsible for finding hosts in a network and getting the
// available shares for each host found.
class SmbShareFinder : public base::SupportsWeakPtr<SmbShareFinder> {
@@ -31,9 +34,16 @@
~SmbShareFinder();
// Gathers the hosts in the network using |scanner_| and gets the shares for
- // each of the hosts found. |callback| will be called once per host and will
- // contain the paths to the shares found (e.g. "smb://host/share").
- void GatherSharesInNetwork(GatherSharesResponse callback);
+ // each of the hosts found. |discovery_callback| runs once when host
+ // disovery is complete. |shares_callback| runs once per host and will contain
+ // the paths to the shares found (e.g. "smb://host/share").
+ void GatherSharesInNetwork(HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback);
+
+ // Gathers the hosts in the network using |scanner_|. Runs
+ // |discovery_callback| upon completion. No data is returned to the caller,
+ // but hosts are cached in |scanner_| and can be used for name resolution.
+ void DiscoverHostsInNetwork(HostDiscoveryResponse discovery_callback);
// Registers HostLocator |locator| to |scanner_|.
void RegisterHostLocator(std::unique_ptr<HostLocator> locator);
@@ -43,14 +53,20 @@
std::string GetResolvedUrl(const SmbUrl& url) const;
private:
+ // Handles the response from discovering hosts in the network.
+ void OnHostsDiscovered(HostDiscoveryResponse discovery_callback,
+ bool success,
+ const HostMap& hosts);
+
// Handles the response from finding hosts in the network.
- void OnHostsFound(GatherSharesResponse callback,
+ void OnHostsFound(HostDiscoveryResponse discovery_callback,
+ GatherSharesResponse shares_callback,
bool success,
const HostMap& hosts);
// Handles the response from getting shares for a given host.
void OnSharesFound(const std::string& host_name,
- GatherSharesResponse callback,
+ GatherSharesResponse shares_callback,
smbprovider::ErrorType error,
const smbprovider::DirectoryEntryListProto& entries);
diff --git a/chrome/browser/chromeos/smb_client/smb_share_finder_unittest.cc b/chrome/browser/chromeos/smb_client/smb_share_finder_unittest.cc
index 90a7f30..6cf9205 100644
--- a/chrome/browser/chromeos/smb_client/smb_share_finder_unittest.cc
+++ b/chrome/browser/chromeos/smb_client/smb_share_finder_unittest.cc
@@ -7,7 +7,8 @@
#include <algorithm>
#include <string>
-#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/smb_client/discovery/in_memory_host_locator.h"
#include "chrome/browser/chromeos/smb_client/smb_constants.h"
@@ -67,14 +68,22 @@
// Helper function when expecting shares to be found in the network.
void ExpectSharesFound() {
- share_finder_->GatherSharesInNetwork(base::BindRepeating(
- &SmbShareFinderTest::SharesFoundCallback, base::Unretained(this)));
+ share_finder_->GatherSharesInNetwork(
+ base::BindOnce(&SmbShareFinderTest::HostsDiscoveredCallback,
+ base::Unretained(this)),
+ base::BindRepeating(&SmbShareFinderTest::SharesFoundCallback,
+ base::Unretained(this)));
+ EXPECT_TRUE(discovery_callback_called_);
}
// Helper function when expecting no shares to be found in the network.
void ExpectNoSharesFound() {
- share_finder_->GatherSharesInNetwork(base::BindRepeating(
- &SmbShareFinderTest::EmptySharesCallback, base::Unretained(this)));
+ share_finder_->GatherSharesInNetwork(
+ base::BindOnce(&SmbShareFinderTest::HostsDiscoveredCallback,
+ base::Unretained(this)),
+ base::BindRepeating(&SmbShareFinderTest::EmptySharesCallback,
+ base::Unretained(this)));
+ EXPECT_TRUE(discovery_callback_called_);
}
// Helper function that expects expected_shares_ to be empty.
@@ -86,7 +95,9 @@
}
private:
- // Removes shares discovered from expected_shares_.
+ void HostsDiscoveredCallback() { discovery_callback_called_ = true; }
+
+ // Removes shares discovered from |expected_shares_|.
void SharesFoundCallback(const std::vector<SmbUrl>& shares_found) {
EXPECT_GE(shares_found.size(), 0u);
@@ -99,6 +110,8 @@
EXPECT_EQ(0u, shares_found.size());
}
+ bool discovery_callback_called_ = false;
+
// Keeps track of expected shares across multiple hosts.
std::set<std::string> expected_shares_;