Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Unified Diff: chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc

Issue 2574173002: mediaview: Implement ArcDocumentsProviderRoot. (Closed)
Patch Set: Address lhchavez's comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
index aa1b86890526123ae9f5168754b6ce218dc540b8..00aac3e1a84f0924291b835a313efc8337e13e6a 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
@@ -4,16 +4,43 @@
#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h"
+#include "base/files/file.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_document.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.h"
#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
using content::BrowserThread;
+using EntryList = storage::AsyncFileUtil::EntryList;
namespace arc {
+namespace {
+
+base::FilePath StripBaseName(const base::FilePath& path) {
+ base::FilePath dirname = path.DirName();
+ // base::FilePath::DirName() returns kCurrentDirectory if the path does not
+ // contain separators. In this case we want an empty path.
+ if (dirname.value() == base::FilePath::kCurrentDirectory) {
+ return base::FilePath();
+ }
+ return dirname;
+}
+
+} // namespace
+
ArcDocumentsProviderRoot::ArcDocumentsProviderRoot(
const std::string& authority,
- const std::string& root_document_id) {}
+ const std::string& root_document_id)
+ : authority_(authority),
+ root_directory_(
+ base::MakeUnique<ArcDocumentsProviderDocument>(root_document_id,
+ true)),
+ weak_ptr_factory_(this) {}
ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -23,14 +50,177 @@ void ArcDocumentsProviderRoot::GetFileInfo(
const base::FilePath& path,
const GetFileInfoCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- NOTIMPLEMENTED(); // TODO(crbug.com/671511): Implement this function.
+ // Skip a cache update if possible.
+ ArcDocumentsProviderDocument* entry = root_directory_->Lookup(path);
+ if (entry) {
+ GetFileInfoAfterCacheUpdate(path, callback);
+ return;
+ }
+ DCHECK(!path.empty());
+ UpdateDirectoryCacheUpTo(
+ StripBaseName(path),
+ base::Bind(&ArcDocumentsProviderRoot::GetFileInfoAfterCacheUpdate,
Luis Héctor Chávez 2016/12/15 23:54:26 nit: #include "base/bind.h"
Shuhei Takahashi 2016/12/16 05:47:14 Done.
+ weak_ptr_factory_.GetWeakPtr(), path, callback));
}
void ArcDocumentsProviderRoot::ReadDirectory(
const base::FilePath& path,
const ReadDirectoryCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- NOTIMPLEMENTED(); // TODO(crbug.com/671511): Implement this function.
+ if (path.empty()) {
+ ReadDirectoryAfterCacheUpdate(path, callback);
+ return;
+ }
+ UpdateDirectoryCacheUpTo(
+ StripBaseName(path),
+ base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryAfterCacheUpdate,
+ weak_ptr_factory_.GetWeakPtr(), path, callback));
+}
+
+void ArcDocumentsProviderRoot::GetFileInfoAfterCacheUpdate(
+ const base::FilePath& path,
+ const GetFileInfoCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ArcDocumentsProviderDocument* entry = root_directory_->Lookup(path);
+ if (!entry) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
+ return;
+ }
+ file_system_instance_util::GetDocumentOnIOThread(
+ authority_, entry->document_id(),
+ base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocument,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void ArcDocumentsProviderRoot::GetFileInfoWithDocument(
+ const GetFileInfoCallback& callback,
+ mojom::DocumentPtr document) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (document.is_null()) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
+ return;
+ }
+
+ base::File::Info info;
+ info.size = document->size;
+ info.is_directory = document->mime_type == kAndroidDirectoryMimeType;
+ info.is_symbolic_link = false;
+ info.last_modified = info.last_accessed = info.creation_time =
+ base::Time::FromDoubleT(document->last_modified / 1000.0);
Luis Héctor Chávez 2016/12/15 23:54:26 nit: base::Time::FromJavaTime(document->last_modif
Shuhei Takahashi 2016/12/16 05:47:14 Thanks, that should be better.
+ callback.Run(base::File::FILE_OK, info);
+}
+
+void ArcDocumentsProviderRoot::ReadDirectoryAfterCacheUpdate(
+ const base::FilePath& path,
+ const ReadDirectoryCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ArcDocumentsProviderDocument* parent_directory =
+ root_directory_->Lookup(path);
+ if (!parent_directory || !parent_directory->is_directory()) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(),
+ false /* has_more */);
+ return;
+ }
+ file_system_instance_util::GetChildDocumentsOnIOThread(
+ authority_, parent_directory->document_id(),
+ base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithChildDocuments,
+ weak_ptr_factory_.GetWeakPtr(), path, callback));
+}
+
+void ArcDocumentsProviderRoot::ReadDirectoryWithChildDocuments(
+ const base::FilePath& path,
+ const ReadDirectoryCallback& callback,
+ base::Optional<std::vector<mojom::DocumentPtr>> children) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!children) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(),
+ false /* has_more */);
+ return;
+ }
+
+ ArcDocumentsProviderDocument* parent_directory =
+ root_directory_->Lookup(path);
+ if (!parent_directory || !parent_directory->is_directory()) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(),
+ false /* has_more */);
+ return;
+ }
+ parent_directory->UpdateWithChildDocuments(children.value());
+
+ std::vector<storage::DirectoryEntry> entry_list;
+ for (const auto& pair : parent_directory->children()) {
+ entry_list.emplace_back(pair.first, pair.second->is_directory()
+ ? storage::DirectoryEntry::DIRECTORY
+ : storage::DirectoryEntry::FILE);
+ }
+ callback.Run(base::File::FILE_OK, entry_list, false /* has_more */);
+}
+
+void ArcDocumentsProviderRoot::UpdateDirectoryCacheUpTo(
+ const base::FilePath& path,
+ const base::Closure& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ UpdateDirectoryCacheIter(base::FilePath(), path, callback);
+}
+
+void ArcDocumentsProviderRoot::UpdateDirectoryCacheIter(
+ const base::FilePath& parent_directory_path,
+ const base::FilePath& remaining_path,
+ const base::Closure& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ ArcDocumentsProviderDocument* parent_directory =
+ root_directory_->Lookup(parent_directory_path);
+ if (!parent_directory || !parent_directory->is_directory()) {
+ callback.Run();
+ return;
+ }
+
+ file_system_instance_util::GetChildDocumentsOnIOThread(
+ authority_, parent_directory->document_id(),
+ base::Bind(
+ &ArcDocumentsProviderRoot::UpdateDirectoryCacheIterWithChildDocuments,
+ weak_ptr_factory_.GetWeakPtr(), parent_directory_path, remaining_path,
+ callback));
+}
+
+void ArcDocumentsProviderRoot::UpdateDirectoryCacheIterWithChildDocuments(
+ const base::FilePath& parent_directory_path,
+ const base::FilePath& remaining_path,
+ const base::Closure& callback,
+ base::Optional<std::vector<mojom::DocumentPtr>> children) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!children) {
+ callback.Run();
+ return;
+ }
+
+ ArcDocumentsProviderDocument* parent_directory =
+ root_directory_->Lookup(parent_directory_path);
+ if (!parent_directory || !parent_directory->is_directory()) {
+ callback.Run();
+ return;
+ }
+ parent_directory->UpdateWithChildDocuments(children.value());
+
+ if (remaining_path.empty()) {
+ callback.Run();
+ return;
+ }
+
+ using Components = std::vector<base::FilePath::StringType>;
+ Components components;
+ remaining_path.GetComponents(&components);
+ DCHECK(!components.empty());
+
+ base::FilePath next_parent_directory_path =
+ parent_directory_path.Append(components[0]);
+ base::FilePath next_remaining_path =
+ base::FilePath::FromUTF8Unsafe(base::JoinString(
+ Components(components.begin() + 1, components.end()), "/"));
+
+ UpdateDirectoryCacheIter(next_parent_directory_path, next_remaining_path,
+ callback);
}
} // namespace arc

Powered by Google App Engine
This is Rietveld 408576698