Commit aa4f22e9 authored by Satoshi Niwa's avatar Satoshi Niwa Committed by Commit Bot

Update path_util::ConvertToContentUrl to handling multiple URLs at a time.

Background:
* We are migrating callers of ConvertPathToArcUrl (sync) to using ConvertToContentUrl (async) instead.
* exo_parts.cc (a caller of ConvertToContentUrl) needs to handle multiple URLs at a time,
  so it converts single-URL callbacks to multiple-URLs callback using BarrierClosure.
* It turns out arc_file_tasks.cc (a caller of ConvertPathToArcUrl) also needs to handle multiple URLs at a time.
* Moving the BarrierClosure logic from exo_parts to path_util, so we don't need to duplicate the same BarrierClosure logic in arc_file_tasks after migration.

Bug: chromium:811679
Test: unit_test
Change-Id: I461651bac3e5110afdd7b97d39576436cb3a92fd
Reviewed-on: https://chromium-review.googlesource.com/983335Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Reviewed-by: default avatarDaichi Hirono <hirono@chromium.org>
Reviewed-by: default avatarShuhei Takahashi <nya@chromium.org>
Commit-Queue: Satoshi Niwa <niwa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547406}
parent d73a1b6b
......@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "base/barrier_closure.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h"
......@@ -47,9 +48,19 @@ Profile* GetPrimaryProfile() {
return chromeos::ProfileHelper::Get()->GetProfileByUser(primary_user);
}
void OnContentUrlResolved(ConvertToContentUrlCallback callback,
const GURL& url) {
std::move(callback).Run(url);
// Helper function for |ConvertToContentUrls|.
void OnSingleContentUrlResolved(const base::RepeatingClosure& barrier_closure,
std::vector<GURL>* out_urls,
size_t index,
const GURL& url) {
(*out_urls)[index] = url;
barrier_closure.Run();
}
// Helper function for |ConvertToContentUrls|.
void OnAllContentUrlsResolved(ConvertToContentUrlsCallback callback,
std::unique_ptr<std::vector<GURL>> urls) {
std::move(callback).Run(*urls);
}
} // namespace
......@@ -143,42 +154,57 @@ bool ConvertPathToArcUrl(const base::FilePath& path, GURL* arc_url_out) {
return false;
}
void ConvertToContentUrl(const storage::FileSystemURL& file_system_url,
ConvertToContentUrlCallback callback) {
void ConvertToContentUrls(
const std::vector<storage::FileSystemURL>& file_system_urls,
ConvertToContentUrlsCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
GURL arc_url;
if (file_system_url.mount_type() == storage::kFileSystemTypeExternal &&
ConvertPathToArcUrl(file_system_url.path(), &arc_url)) {
std::move(callback).Run(arc_url);
return;
}
Profile* primary_profile = GetPrimaryProfile();
if (!primary_profile) {
std::move(callback).Run(GURL());
if (file_system_urls.empty()) {
std::move(callback).Run(std::vector<GURL>());
return;
}
Profile* profile = GetPrimaryProfile();
auto* documents_provider_root_map =
arc::ArcDocumentsProviderRootMap::GetForBrowserContext(primary_profile);
if (!documents_provider_root_map) {
std::move(callback).Run(GURL());
return;
profile ? arc::ArcDocumentsProviderRootMap::GetForBrowserContext(profile)
: nullptr;
// To keep the original order, prefill |out_urls| with empty URLs and
// specify index when updating it like (*out_urls)[index] = url.
auto out_urls = std::make_unique<std::vector<GURL>>(file_system_urls.size());
auto* out_urls_ptr = out_urls.get();
auto barrier = base::BarrierClosure(
file_system_urls.size(),
base::BindOnce(&OnAllContentUrlsResolved, std::move(callback),
std::move(out_urls)));
auto single_content_url_callback =
base::BindRepeating(&OnSingleContentUrlResolved, barrier, out_urls_ptr);
for (size_t index = 0; index < file_system_urls.size(); ++index) {
const auto& file_system_url = file_system_urls[index];
GURL arc_url;
if (file_system_url.mount_type() == storage::kFileSystemTypeExternal &&
ConvertPathToArcUrl(file_system_url.path(), &arc_url)) {
single_content_url_callback.Run(index, arc_url);
continue;
}
if (!documents_provider_root_map) {
single_content_url_callback.Run(index, GURL());
continue;
}
base::FilePath filepath;
auto* documents_provider_root =
documents_provider_root_map->ParseAndLookup(file_system_url, &filepath);
if (!documents_provider_root) {
single_content_url_callback.Run(index, GURL());
continue;
}
documents_provider_root->ResolveToContentUrl(
filepath, base::BindRepeating(single_content_url_callback, index));
}
base::FilePath file_path;
auto* documents_provider_root =
documents_provider_root_map->ParseAndLookup(file_system_url, &file_path);
if (!documents_provider_root) {
std::move(callback).Run(GURL());
return;
}
// TODO(niwa): Remove OnContentUrlResolved once ResolveToContentUrl is
// migrated from base::Callback to base::OnceCallback.
documents_provider_root->ResolveToContentUrl(
file_path, base::Bind(&OnContentUrlResolved, base::Passed(&callback)));
}
} // namespace util
......
......@@ -43,20 +43,22 @@ bool MigratePathFromOldFormat(Profile* profile,
// The canonical mount point name for "Downloads" folder.
std::string GetDownloadsMountPointName(Profile* profile);
// DEPRECATED. Use |ConvertToContentUrl| instead.
// DEPRECATED. Use |ConvertToContentUrls| instead.
// While this function can convert paths under Downloads, /media/removable
// and /special/drive, this CANNOT convert paths under ARC media directories
// (/special/arc-documents-provider).
// TODO(crbug.com/811679): Migrate all callers and remove this.
bool ConvertPathToArcUrl(const base::FilePath& path, GURL* arc_url_out);
using ConvertToContentUrlCallback =
base::OnceCallback<void(const GURL& content_url)>;
using ConvertToContentUrlsCallback =
base::OnceCallback<void(const std::vector<GURL>& content_urls)>;
// Asynchronously converts a Chrome OS file system URL to a content:// URL.
// Returns an empty GURL if |file_system_url| is not convertible.
void ConvertToContentUrl(const storage::FileSystemURL& file_system_url,
ConvertToContentUrlCallback callback);
// Asynchronously converts Chrome OS file system URLs to content:// URLs.
// Always returns a vector of the same size as |file_system_urls|.
// Empty GURLs are filled in the vector if conversion fails.
void ConvertToContentUrls(
const std::vector<storage::FileSystemURL>& file_system_urls,
ConvertToContentUrlsCallback callback);
} // namespace util
} // namespace file_manager
......
......@@ -10,7 +10,6 @@
#include <glib.h>
#endif
#include "base/barrier_closure.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
......@@ -73,20 +72,6 @@ void GetFileSystemUrlsFromPickle(
}
}
// Helper function for |GetUrlsFromPickle|.
void OnSingleUrlResolved(const base::RepeatingClosure& barrier_closure,
std::vector<GURL>* out_urls,
const GURL& url) {
out_urls->push_back(url);
barrier_closure.Run();
}
// Helper function for |GetUrlsFromPickle|.
void OnAllUrlsResolved(exo::FileHelper::UrlsFromPickleCallback callback,
std::unique_ptr<std::vector<GURL>> urls) {
std::move(callback).Run(*urls);
}
class ChromeFileHelper : public exo::FileHelper {
public:
ChromeFileHelper() = default;
......@@ -118,19 +103,8 @@ class ChromeFileHelper : public exo::FileHelper {
std::move(callback).Run(std::vector<GURL>());
return;
}
auto out_urls = std::make_unique<std::vector<GURL>>();
auto* out_urls_ptr = out_urls.get();
auto barrier = base::BarrierClosure(
file_system_urls.size(),
base::BindOnce(&OnAllUrlsResolved, std::move(callback),
std::move(out_urls)));
auto convert_url_callback =
base::BindRepeating(&OnSingleUrlResolved, barrier, out_urls_ptr);
for (const auto& file_system_url : file_system_urls) {
file_manager::util::ConvertToContentUrl(file_system_url,
convert_url_callback);
}
file_manager::util::ConvertToContentUrls(file_system_urls,
std::move(callback));
}
};
......
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