Commit 48c65805 authored by Eero Häkkinen's avatar Eero Häkkinen Committed by Commit Bot

[Native File System] Change GetEntries to be asynchronous

This changes NativeFileSystemDirectoryHandle.GetEntries to be
asynchronous like the web-exposed API and the storage implementation.
This should make directory iteration more efficient.

Bug: 970059
Change-Id: I43bdd4950a70abc8d7cd8dcc890963655d49fdcd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1867150Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Auto-Submit: Eero Häkkinen <eero.hakkinen@intel.com>
Commit-Queue: Sam McNally <sammc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708885}
parent 75cc5cb4
...@@ -49,11 +49,6 @@ bool IsCurrentOrParentDirectory(const std::string& name) { ...@@ -49,11 +49,6 @@ bool IsCurrentOrParentDirectory(const std::string& name) {
} // namespace } // namespace
struct NativeFileSystemDirectoryHandleImpl::ReadDirectoryState {
GetEntriesCallback callback;
std::vector<NativeFileSystemEntryPtr> entries;
};
NativeFileSystemDirectoryHandleImpl::NativeFileSystemDirectoryHandleImpl( NativeFileSystemDirectoryHandleImpl::NativeFileSystemDirectoryHandleImpl(
NativeFileSystemManagerImpl* manager, NativeFileSystemManagerImpl* manager,
const BindingContext& context, const BindingContext& context,
...@@ -174,15 +169,20 @@ void NativeFileSystemDirectoryHandleImpl::GetDirectory( ...@@ -174,15 +169,20 @@ void NativeFileSystemDirectoryHandleImpl::GetDirectory(
} }
void NativeFileSystemDirectoryHandleImpl::GetEntries( void NativeFileSystemDirectoryHandleImpl::GetEntries(
GetEntriesCallback callback) { mojo::PendingRemote<blink::mojom::NativeFileSystemDirectoryEntriesListener>
pending_listener) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto listener = std::make_unique<
mojo::Remote<blink::mojom::NativeFileSystemDirectoryEntriesListener>>(
std::move(pending_listener));
listener->reset_on_disconnect();
DoFileSystemOperation( DoFileSystemOperation(
FROM_HERE, &FileSystemOperationRunner::ReadDirectory, FROM_HERE, &FileSystemOperationRunner::ReadDirectory,
base::BindRepeating( base::BindRepeating(
&NativeFileSystemDirectoryHandleImpl::DidReadDirectory, &NativeFileSystemDirectoryHandleImpl::DidReadDirectory,
weak_factory_.GetWeakPtr(), weak_factory_.GetWeakPtr(), base::Owned(std::move(listener))),
base::Owned(new ReadDirectoryState{std::move(callback)})),
url()); url());
} }
...@@ -284,19 +284,24 @@ void NativeFileSystemDirectoryHandleImpl::DidGetDirectory( ...@@ -284,19 +284,24 @@ void NativeFileSystemDirectoryHandleImpl::DidGetDirectory(
} }
void NativeFileSystemDirectoryHandleImpl::DidReadDirectory( void NativeFileSystemDirectoryHandleImpl::DidReadDirectory(
ReadDirectoryState* state, mojo::Remote<blink::mojom::NativeFileSystemDirectoryEntriesListener>*
listener,
base::File::Error result, base::File::Error result,
std::vector<filesystem::mojom::DirectoryEntry> file_list, std::vector<filesystem::mojom::DirectoryEntry> file_list,
bool has_more) { bool has_more_entries) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!*listener)
return;
if (result != base::File::FILE_OK) { if (result != base::File::FILE_OK) {
DCHECK(!has_more); DCHECK(!has_more_entries);
std::move(state->callback) (*listener)->DidReadDirectory(
.Run(native_file_system_error::FromFileError(result), {}); native_file_system_error::FromFileError(result), {}, false);
return; return;
} }
std::vector<NativeFileSystemEntryPtr> entries;
for (const auto& entry : file_list) { for (const auto& entry : file_list) {
std::string basename = storage::FilePathToString(entry.name); std::string basename = storage::FilePathToString(entry.name);
...@@ -308,17 +313,12 @@ void NativeFileSystemDirectoryHandleImpl::DidReadDirectory( ...@@ -308,17 +313,12 @@ void NativeFileSystemDirectoryHandleImpl::DidReadDirectory(
// |basename|. // |basename|.
CHECK_EQ(get_child_url_result->status, NativeFileSystemStatus::kOk); CHECK_EQ(get_child_url_result->status, NativeFileSystemStatus::kOk);
state->entries.push_back( entries.push_back(
CreateEntry(basename, child_url, CreateEntry(basename, child_url,
entry.type == filesystem::mojom::FsFileType::DIRECTORY)); entry.type == filesystem::mojom::FsFileType::DIRECTORY));
} }
(*listener)->DidReadDirectory(native_file_system_error::Ok(),
// TODO(mek): Change API so we can stream back entries as they come in, rather std::move(entries), has_more_entries);
// than waiting till we have retrieved them all.
if (!has_more) {
std::move(state->callback)
.Run(native_file_system_error::Ok(), std::move(state->entries));
}
} }
void NativeFileSystemDirectoryHandleImpl::RemoveEntryImpl( void NativeFileSystemDirectoryHandleImpl::RemoveEntryImpl(
......
...@@ -43,7 +43,9 @@ class NativeFileSystemDirectoryHandleImpl ...@@ -43,7 +43,9 @@ class NativeFileSystemDirectoryHandleImpl
void GetDirectory(const std::string& basename, void GetDirectory(const std::string& basename,
bool create, bool create,
GetDirectoryCallback callback) override; GetDirectoryCallback callback) override;
void GetEntries(GetEntriesCallback callback) override; void GetEntries(mojo::PendingRemote<
blink::mojom::NativeFileSystemDirectoryEntriesListener>
pending_listener) override;
void RemoveEntry(const std::string& basename, void RemoveEntry(const std::string& basename,
bool recurse, bool recurse,
RemoveEntryCallback callback) override; RemoveEntryCallback callback) override;
...@@ -52,9 +54,6 @@ class NativeFileSystemDirectoryHandleImpl ...@@ -52,9 +54,6 @@ class NativeFileSystemDirectoryHandleImpl
override; override;
private: private:
// State that is kept for the duration of a GetEntries/ReadDirectory call.
struct ReadDirectoryState;
// This method creates the file if it does not currently exists. I.e. it is // This method creates the file if it does not currently exists. I.e. it is
// the implementation for passing create=true to GetFile. // the implementation for passing create=true to GetFile.
void GetFileWithWritePermission(const storage::FileSystemURL& child_url, void GetFileWithWritePermission(const storage::FileSystemURL& child_url,
...@@ -70,10 +69,11 @@ class NativeFileSystemDirectoryHandleImpl ...@@ -70,10 +69,11 @@ class NativeFileSystemDirectoryHandleImpl
GetDirectoryCallback callback, GetDirectoryCallback callback,
base::File::Error result); base::File::Error result);
void DidReadDirectory( void DidReadDirectory(
ReadDirectoryState* state, mojo::Remote<blink::mojom::NativeFileSystemDirectoryEntriesListener>*
listener,
base::File::Error result, base::File::Error result,
std::vector<filesystem::mojom::DirectoryEntry> file_list, std::vector<filesystem::mojom::DirectoryEntry> file_list,
bool has_more); bool has_more_entries);
void RemoveEntryImpl(const storage::FileSystemURL& url, void RemoveEntryImpl(const storage::FileSystemURL& url,
bool recurse, bool recurse,
......
...@@ -21,6 +21,15 @@ struct NativeFileSystemEntry { ...@@ -21,6 +21,15 @@ struct NativeFileSystemEntry {
string name; string name;
}; };
interface NativeFileSystemDirectoryEntriesListener {
// Called by NativeFileSystemDirectoryHandle.GetEntries when some entries
// have been obtained. |has_more_entries| is false when all the entries have
// been obtained, and indicates that the callback will not be called again.
DidReadDirectory(NativeFileSystemError result,
array<NativeFileSystemEntry> entries,
bool has_more_entries);
};
// This interface represents a handle to a directory in the Native File System // This interface represents a handle to a directory in the Native File System
// API. // API.
// //
...@@ -55,9 +64,7 @@ interface NativeFileSystemDirectoryHandle { ...@@ -55,9 +64,7 @@ interface NativeFileSystemDirectoryHandle {
pending_remote<NativeFileSystemDirectoryHandle>? directory); pending_remote<NativeFileSystemDirectoryHandle>? directory);
// Returns all the direct children of this directory. // Returns all the direct children of this directory.
// TODO(mek): Change this API to stream results in chunks rather than block GetEntries(pending_remote<NativeFileSystemDirectoryEntriesListener> listener);
// until all entries have been retrieved.
GetEntries() => (NativeFileSystemError result, array<NativeFileSystemEntry> entries);
// Deletes an entry which is a child of this directory. // Deletes an entry which is a child of this directory.
// To delete recursively, set |recurse| to true. // To delete recursively, set |recurse| to true.
......
...@@ -19,9 +19,7 @@ NativeFileSystemDirectoryIterator::NativeFileSystemDirectoryIterator( ...@@ -19,9 +19,7 @@ NativeFileSystemDirectoryIterator::NativeFileSystemDirectoryIterator(
NativeFileSystemDirectoryHandle* directory, NativeFileSystemDirectoryHandle* directory,
ExecutionContext* execution_context) ExecutionContext* execution_context)
: ContextLifecycleObserver(execution_context), directory_(directory) { : ContextLifecycleObserver(execution_context), directory_(directory) {
directory_->MojoHandle()->GetEntries( directory_->MojoHandle()->GetEntries(receiver_.BindNewPipeAndPassRemote());
WTF::Bind(&NativeFileSystemDirectoryIterator::OnGotEntries,
WrapWeakPersistent(this)));
} }
ScriptPromise NativeFileSystemDirectoryIterator::next( ScriptPromise NativeFileSystemDirectoryIterator::next(
...@@ -60,9 +58,10 @@ void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) { ...@@ -60,9 +58,10 @@ void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) {
visitor->Trace(directory_); visitor->Trace(directory_);
} }
void NativeFileSystemDirectoryIterator::OnGotEntries( void NativeFileSystemDirectoryIterator::DidReadDirectory(
mojom::blink::NativeFileSystemErrorPtr result, mojom::blink::NativeFileSystemErrorPtr result,
Vector<mojom::blink::NativeFileSystemEntryPtr> entries) { Vector<mojom::blink::NativeFileSystemEntryPtr> entries,
bool has_more_entries) {
if (!GetExecutionContext()) if (!GetExecutionContext())
return; return;
if (result->status != mojom::blink::NativeFileSystemStatus::kOk) { if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
...@@ -77,7 +76,7 @@ void NativeFileSystemDirectoryIterator::OnGotEntries( ...@@ -77,7 +76,7 @@ void NativeFileSystemDirectoryIterator::OnGotEntries(
entries_.push_back(NativeFileSystemHandle::CreateFromMojoEntry( entries_.push_back(NativeFileSystemHandle::CreateFromMojoEntry(
std::move(e), GetExecutionContext())); std::move(e), GetExecutionContext()));
} }
waiting_for_more_entries_ = false; waiting_for_more_entries_ = has_more_entries;
if (pending_next_) { if (pending_next_) {
ScriptState::Scope scope(pending_next_->GetScriptState()); ScriptState::Scope scope(pending_next_->GetScriptState());
pending_next_->Resolve( pending_next_->Resolve(
...@@ -86,4 +85,8 @@ void NativeFileSystemDirectoryIterator::OnGotEntries( ...@@ -86,4 +85,8 @@ void NativeFileSystemDirectoryIterator::OnGotEntries(
} }
} }
void NativeFileSystemDirectoryIterator::Dispose() {
receiver_.reset();
}
} // namespace blink } // namespace blink
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_DIRECTORY_ITERATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_DIRECTORY_ITERATOR_H_
#include "base/files/file.h" #include "base/files/file.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink-forward.h" #include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
...@@ -20,9 +21,11 @@ class ScriptState; ...@@ -20,9 +21,11 @@ class ScriptState;
class NativeFileSystemDirectoryIterator final class NativeFileSystemDirectoryIterator final
: public ScriptWrappable, : public ScriptWrappable,
public ContextLifecycleObserver { public ContextLifecycleObserver,
public mojom::blink::NativeFileSystemDirectoryEntriesListener {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemDirectoryIterator); USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemDirectoryIterator);
USING_PRE_FINALIZER(NativeFileSystemDirectoryIterator, Dispose);
public: public:
NativeFileSystemDirectoryIterator(NativeFileSystemDirectoryHandle* directory, NativeFileSystemDirectoryIterator(NativeFileSystemDirectoryHandle* directory,
...@@ -33,14 +36,18 @@ class NativeFileSystemDirectoryIterator final ...@@ -33,14 +36,18 @@ class NativeFileSystemDirectoryIterator final
void Trace(Visitor*) override; void Trace(Visitor*) override;
private: private:
void OnGotEntries(mojom::blink::NativeFileSystemErrorPtr result, void DidReadDirectory(mojom::blink::NativeFileSystemErrorPtr result,
Vector<mojom::blink::NativeFileSystemEntryPtr> entries); Vector<mojom::blink::NativeFileSystemEntryPtr> entries,
bool has_more_entries) override;
void Dispose();
mojom::blink::NativeFileSystemErrorPtr error_; mojom::blink::NativeFileSystemErrorPtr error_;
bool waiting_for_more_entries_ = true; bool waiting_for_more_entries_ = true;
HeapDeque<Member<NativeFileSystemHandle>> entries_; HeapDeque<Member<NativeFileSystemHandle>> entries_;
Member<ScriptPromiseResolver> pending_next_; Member<ScriptPromiseResolver> pending_next_;
Member<NativeFileSystemDirectoryHandle> directory_; Member<NativeFileSystemDirectoryHandle> directory_;
mojo::Receiver<mojom::blink::NativeFileSystemDirectoryEntriesListener>
receiver_{this};
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment