smbprovider: Add ReadDirectory and GetMetadataEntry
Add ReadDirectory and GetMetadataEntry methods for SmbProviderClient.
This allows read-only navigation of the share, excluding reading files.
Bug:chromium:757625
CQ-DEPEND=CL:794892
Change-Id: I55d4baa6dec95392774cdea3c07c13989b31e782
Reviewed-on: https://chromium-review.googlesource.com/749897
Commit-Queue: Allen Vicencio <allenvic@chromium.org>
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: Dan Erat <derat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523259}
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index 4caa662b..b676e9a 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/smb_client/smb_service.h"
+#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
#include "chrome/browser/chromeos/smb_client/smb_file_system.h"
@@ -35,7 +36,7 @@
}
void SmbService::Mount(const file_system_provider::MountOptions& options,
- const std::string& share_path,
+ const base::FilePath& share_path,
MountResponse callback) {
chromeos::DBusThreadManager::Get()->GetSmbProviderClient()->Mount(
share_path, base::BindOnce(&SmbService::OnMountResponse,
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h
index ce685aa9..3404adb 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.h
+++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -18,6 +18,10 @@
#include "chromeos/dbus/smb_provider_client.h"
#include "components/keyed_service/core/keyed_service.h"
+namespace base {
+class FilePath;
+} // namespace base
+
namespace chromeos {
namespace smb_client {
@@ -42,7 +46,7 @@
// Starts the process of mounting an SMB file system.
// Calls SmbProviderClient::Mount().
void Mount(const file_system_provider::MountOptions& options,
- const std::string& share_path,
+ const base::FilePath& share_path,
MountResponse callback);
// Completes the mounting of an SMB file system, passing |options| on to
diff --git a/chromeos/dbus/fake_smb_provider_client.cc b/chromeos/dbus/fake_smb_provider_client.cc
index 54eec61..45c135f 100644
--- a/chromeos/dbus/fake_smb_provider_client.cc
+++ b/chromeos/dbus/fake_smb_provider_client.cc
@@ -4,7 +4,6 @@
#include "chromeos/dbus/fake_smb_provider_client.h"
-#include <string>
#include <utility>
#include "base/bind.h"
@@ -19,7 +18,7 @@
void FakeSmbProviderClient::Init(dbus::Bus* bus) {}
-void FakeSmbProviderClient::Mount(const std::string& share_path,
+void FakeSmbProviderClient::Mount(const base::FilePath& share_path,
MountCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), smbprovider::ERROR_OK, 1));
@@ -31,4 +30,22 @@
FROM_HERE, base::BindOnce(std::move(callback), smbprovider::ERROR_OK));
}
+void FakeSmbProviderClient::ReadDirectory(int32_t mount_id,
+ const base::FilePath& directory_path,
+ ReadDirectoryCallback callback) {
+ smbprovider::DirectoryEntryList entry_list;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), smbprovider::ERROR_OK, entry_list));
+}
+
+void FakeSmbProviderClient::GetMetadataEntry(int32_t mount_id,
+ const base::FilePath& entry_path,
+ GetMetdataEntryCallback callback) {
+ smbprovider::DirectoryEntry entry;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), smbprovider::ERROR_OK, entry));
+}
+
} // namespace chromeos
diff --git a/chromeos/dbus/fake_smb_provider_client.h b/chromeos/dbus/fake_smb_provider_client.h
index 3b46101..c794ae6 100644
--- a/chromeos/dbus/fake_smb_provider_client.h
+++ b/chromeos/dbus/fake_smb_provider_client.h
@@ -19,8 +19,14 @@
void Init(dbus::Bus* bus) override;
// SmbProviderClient override.
- void Mount(const std::string& share_path, MountCallback callback) override;
+ void Mount(const base::FilePath& share_path, MountCallback callback) override;
void Unmount(int32_t mount_id, UnmountCallback callback) override;
+ void ReadDirectory(int32_t mount_id,
+ const base::FilePath& directory_path,
+ ReadDirectoryCallback callback) override;
+ void GetMetadataEntry(int32_t mount_id,
+ const base::FilePath& entry_path,
+ GetMetdataEntryCallback callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(FakeSmbProviderClient);
diff --git a/chromeos/dbus/smb_provider_client.cc b/chromeos/dbus/smb_provider_client.cc
index 1858238e..f0d0fea6 100644
--- a/chromeos/dbus/smb_provider_client.cc
+++ b/chromeos/dbus/smb_provider_client.cc
@@ -26,18 +26,38 @@
return static_cast<smbprovider::ErrorType>(int_error);
}
+smbprovider::ErrorType GetErrorAndProto(
+ dbus::Response* response,
+ google::protobuf::MessageLite* protobuf_out) {
+ if (!response) {
+ DLOG(ERROR) << "Failed to call smbprovider";
+ return smbprovider::ERROR_DBUS_PARSE_FAILED;
+ }
+ dbus::MessageReader reader(response);
+ smbprovider::ErrorType error(GetErrorFromReader(&reader));
+ if (error != smbprovider::ERROR_OK) {
+ return error;
+ }
+ if (!reader.PopArrayOfBytesAsProto(protobuf_out)) {
+ DLOG(ERROR) << "Failed to parse protobuf.";
+ return smbprovider::ERROR_DBUS_PARSE_FAILED;
+ }
+ return smbprovider::ERROR_OK;
+}
+
class SmbProviderClientImpl : public SmbProviderClient {
public:
SmbProviderClientImpl() : weak_ptr_factory_(this) {}
~SmbProviderClientImpl() override {}
- void Mount(const std::string& share_path, MountCallback callback) override {
+ void Mount(const base::FilePath& share_path,
+ MountCallback callback) override {
dbus::MethodCall method_call(smbprovider::kSmbProviderInterface,
smbprovider::kMountMethod);
dbus::MessageWriter writer(&method_call);
smbprovider::MountOptions mount_options;
- mount_options.set_path(share_path);
+ mount_options.set_path(share_path.value());
writer.AppendProtoAsArrayOfBytes(mount_options);
proxy_->CallMethod(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
@@ -58,6 +78,42 @@
weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
}
+ void ReadDirectory(int32_t mount_id,
+ const base::FilePath& directory_path,
+ ReadDirectoryCallback callback) override {
+ dbus::MethodCall method_call(smbprovider::kSmbProviderInterface,
+ smbprovider::kReadDirectoryMethod);
+ dbus::MessageWriter writer(&method_call);
+ smbprovider::ReadDirectoryOptions read_directory_options;
+ read_directory_options.set_mount_id(mount_id);
+ read_directory_options.set_directory_path(directory_path.value());
+ writer.AppendProtoAsArrayOfBytes(read_directory_options);
+ proxy_->CallMethod(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::BindOnce(&SmbProviderClientImpl::HandleProtoCallback<
+ smbprovider::DirectoryEntryList>,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&callback)));
+ }
+
+ void GetMetadataEntry(int32_t mount_id,
+ const base::FilePath& entry_path,
+ GetMetdataEntryCallback callback) override {
+ dbus::MethodCall method_call(smbprovider::kSmbProviderInterface,
+ smbprovider::kGetMetadataEntryMethod);
+ dbus::MessageWriter writer(&method_call);
+ smbprovider::GetMetadataEntryOptions get_metadata_entry_options;
+ get_metadata_entry_options.set_mount_id(mount_id);
+ get_metadata_entry_options.set_entry_path(entry_path.value());
+ writer.AppendProtoAsArrayOfBytes(get_metadata_entry_options);
+ proxy_->CallMethod(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::BindOnce(&SmbProviderClientImpl::HandleProtoCallback<
+ smbprovider::DirectoryEntry>,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&callback)));
+ }
+
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
@@ -101,6 +157,17 @@
std::move(callback).Run(GetErrorFromReader(&reader));
}
+ // Handles D-Bus responses for methods that return an error and a protobuf
+ // object.
+ template <class T>
+ void HandleProtoCallback(base::OnceCallback<void(smbprovider::ErrorType error,
+ const T& response)> callback,
+ dbus::Response* response) {
+ T proto;
+ smbprovider::ErrorType error(GetErrorAndProto(response, &proto));
+ std::move(callback).Run(error, proto);
+ }
+
dbus::ObjectProxy* proxy_ = nullptr;
// Note: This should remain the last member so it'll be destroyed and
diff --git a/chromeos/dbus/smb_provider_client.h b/chromeos/dbus/smb_provider_client.h
index 776177f..94ba9cf6 100644
--- a/chromeos/dbus/smb_provider_client.h
+++ b/chromeos/dbus/smb_provider_client.h
@@ -5,10 +5,8 @@
#ifndef CHROMEOS_DBUS_SMB_PROVIDER_CLIENT_H_
#define CHROMEOS_DBUS_SMB_PROVIDER_CLIENT_H_
-#include <string>
-
-#include <base/callback.h>
-
+#include "base/callback.h"
+#include "base/files/file_path.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/smbprovider/directory_entry.pb.h"
@@ -26,6 +24,12 @@
base::OnceCallback<void(smbprovider::ErrorType error, int32_t mount_id)>;
using UnmountCallback =
base::OnceCallback<void(smbprovider::ErrorType error)>;
+ using ReadDirectoryCallback =
+ base::OnceCallback<void(smbprovider::ErrorType error,
+ const smbprovider::DirectoryEntryList& entries)>;
+ using GetMetdataEntryCallback =
+ base::OnceCallback<void(smbprovider::ErrorType error,
+ const smbprovider::DirectoryEntry& entry)>;
~SmbProviderClient() override;
@@ -36,12 +40,27 @@
// Calls Mount. It runs OpenDirectory() on |share_path| to check that it is a
// valid share. |callback| is called after getting (or failing to get) D-BUS
// response.
- virtual void Mount(const std::string& share_path, MountCallback callback) = 0;
+ virtual void Mount(const base::FilePath& share_path,
+ MountCallback callback) = 0;
// Calls Unmount. This removes the corresponding mount of |mount_id| from
// the list of valid mounts. Subsequent operations on |mount_id| will fail.
virtual void Unmount(int32_t mount_id, UnmountCallback callback) = 0;
+ // Calls ReadDirectory. Using the corresponding mount of |mount_id|, this
+ // reads the directory on a given |directory_path| and passes the
+ // DirectoryEntryList to the supplied ReadDirectoryCallback.
+ virtual void ReadDirectory(int32_t mount_id,
+ const base::FilePath& directory_path,
+ ReadDirectoryCallback callback) = 0;
+
+ // Calls GetMetadataEntry. Using the corresponding mount of |mount_id|, this
+ // reads an entry in a given |entry_path| and passes the DirectoryEntry to the
+ // supplied GetMetadataEntryCallback.
+ virtual void GetMetadataEntry(int32_t mount_id,
+ const base::FilePath& entry_path,
+ GetMetdataEntryCallback callback) = 0;
+
protected:
// Create() should be used instead.
SmbProviderClient();