Commit 388c3850 authored by Bo Majewski's avatar Bo Majewski Committed by Commit Bot

Files App: Enable future generation of thumbnails for local files

Adds basic scaffolding for local file thumbnail generation:
- Moves GetThumbnail function from private_api_drive to private_api_misc
- Adds code that directs the flow of thumbnail generation based on file
  system type
- Adds a place holder for local thumbnail generation.

Bug: 903742
Change-Id: I4b4326d9b28b81a5b46266a7ee03dede5878119e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2246209
Commit-Queue: Bo Majewski <majewski@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780165}
parent 06fa7cfc
...@@ -506,16 +506,6 @@ class SingleEntryPropertiesGetterForDocumentsProvider { ...@@ -506,16 +506,6 @@ class SingleEntryPropertiesGetterForDocumentsProvider {
weak_ptr_factory_{this}; weak_ptr_factory_{this};
}; // class SingleEntryPropertiesGetterForDocumentsProvider }; // class SingleEntryPropertiesGetterForDocumentsProvider
std::string MakeThumbnailDataUrlOnThreadPool(
const std::vector<uint8_t>& png_data) {
std::string encoded;
base::Base64Encode(
base::StringPiece(reinterpret_cast<const char*>(png_data.data()),
png_data.size()),
&encoded);
return base::StrCat({"data:image/png;base64,", encoded});
}
void OnSearchDriveFs( void OnSearchDriveFs(
scoped_refptr<ExtensionFunction> function, scoped_refptr<ExtensionFunction> function,
bool filter_dirs, bool filter_dirs,
...@@ -1105,71 +1095,4 @@ void FileManagerPrivateInternalGetDownloadUrlFunction::OnGotMetadata( ...@@ -1105,71 +1095,4 @@ void FileManagerPrivateInternalGetDownloadUrlFunction::OnGotMetadata(
OnGotDownloadUrl(metadata ? GURL(metadata->download_url) : GURL()); OnGotDownloadUrl(metadata ? GURL(metadata->download_url) : GURL());
} }
FileManagerPrivateInternalGetThumbnailFunction::
FileManagerPrivateInternalGetThumbnailFunction() {
SetWarningThresholds(kDriveSlowOperationThreshold,
kDriveVerySlowOperationThreshold);
}
FileManagerPrivateInternalGetThumbnailFunction::
~FileManagerPrivateInternalGetThumbnailFunction() = default;
ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetThumbnailFunction::Run() {
using extensions::api::file_manager_private_internal::GetThumbnail::Params;
const std::unique_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
const ChromeExtensionFunctionDetails chrome_details(this);
scoped_refptr<storage::FileSystemContext> file_system_context =
file_manager::util::GetFileSystemContextForRenderFrameHost(
chrome_details.GetProfile(), render_frame_host());
const GURL url = GURL(params->url);
const storage::FileSystemURL file_system_url =
file_system_context->CrackURL(url);
if (file_system_url.type() != storage::kFileSystemTypeDriveFs) {
return RespondNow(Error("Invalid URL"));
}
drive::DriveIntegrationService* integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(
chrome_details.GetProfile());
base::FilePath path;
if (!integration_service || !integration_service->GetRelativeDrivePath(
file_system_url.path(), &path)) {
return RespondNow(Error("Drive not available"));
}
auto* drivefs_interface = integration_service->GetDriveFsInterface();
if (!drivefs_interface) {
return RespondNow(Error("Drive not available"));
}
drivefs_interface->GetThumbnail(
path, params->crop_to_square,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(
&FileManagerPrivateInternalGetThumbnailFunction::GotThumbnail,
this),
base::Optional<std::vector<uint8_t>>()));
return RespondLater();
}
void FileManagerPrivateInternalGetThumbnailFunction::GotThumbnail(
const base::Optional<std::vector<uint8_t>>& data) {
if (!data) {
Respond(OneArgument(std::make_unique<base::Value>("")));
return;
}
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, base::BindOnce(&MakeThumbnailDataUrlOnThreadPool, *data),
base::BindOnce(
&FileManagerPrivateInternalGetThumbnailFunction::SendEncodedThumbnail,
this));
}
void FileManagerPrivateInternalGetThumbnailFunction::SendEncodedThumbnail(
std::string thumbnail_data_url) {
Respond(OneArgument(
std::make_unique<base::Value>(std::move(thumbnail_data_url))));
}
} // namespace extensions } // namespace extensions
...@@ -178,26 +178,6 @@ class FileManagerPrivateInternalGetDownloadUrlFunction ...@@ -178,26 +178,6 @@ class FileManagerPrivateInternalGetDownloadUrlFunction
std::unique_ptr<google_apis::AuthService> auth_service_; std::unique_ptr<google_apis::AuthService> auth_service_;
}; };
class FileManagerPrivateInternalGetThumbnailFunction
: public LoggedExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getThumbnail",
FILEMANAGERPRIVATEINTERNAL_GETTHUMBNAIL)
FileManagerPrivateInternalGetThumbnailFunction();
protected:
~FileManagerPrivateInternalGetThumbnailFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
private:
void GotThumbnail(const base::Optional<std::vector<uint8_t>>& data);
void SendEncodedThumbnail(std::string thumbnail_data_url);
};
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_DRIVE_H_ #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_DRIVE_H_
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/i18n/encoding_detection.h" #include "base/i18n/encoding_detection.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
...@@ -73,6 +74,7 @@ ...@@ -73,6 +74,7 @@
#include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/app_window_registry.h"
#include "google_apis/drive/auth_service.h" #include "google_apis/drive/auth_service.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
#include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_types.h"
#include "storage/common/file_system/file_system_util.h" #include "storage/common/file_system/file_system_util.h"
...@@ -195,6 +197,17 @@ bool IsAllowedSource(storage::FileSystemType type, ...@@ -195,6 +197,17 @@ bool IsAllowedSource(storage::FileSystemType type,
} }
} }
// Encodes PNG data as a dataURL.
std::string MakeThumbnailDataUrlOnThreadPool(
const std::vector<uint8_t>& png_data) {
std::string encoded;
base::Base64Encode(
base::StringPiece(reinterpret_cast<const char*>(png_data.data()),
png_data.size()),
&encoded);
return base::StrCat({"data:image/png;base64,", encoded});
}
} // namespace } // namespace
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
...@@ -1110,4 +1123,105 @@ FileManagerPrivateDetectCharacterEncodingFunction::Run() { ...@@ -1110,4 +1123,105 @@ FileManagerPrivateDetectCharacterEncodingFunction::Run() {
success ? std::move(encoding) : std::string()))); success ? std::move(encoding) : std::string())));
} }
FileManagerPrivateInternalGetThumbnailFunction::
FileManagerPrivateInternalGetThumbnailFunction() {}
FileManagerPrivateInternalGetThumbnailFunction::
~FileManagerPrivateInternalGetThumbnailFunction() = default;
ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetThumbnailFunction::Run() {
using extensions::api::file_manager_private_internal::GetThumbnail::Params;
const std::unique_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
const ChromeExtensionFunctionDetails chrome_details(this);
scoped_refptr<storage::FileSystemContext> file_system_context =
file_manager::util::GetFileSystemContextForRenderFrameHost(
chrome_details.GetProfile(), render_frame_host());
const GURL url = GURL(params->url);
const storage::FileSystemURL file_system_url =
file_system_context->CrackURL(url);
switch (file_system_url.type()) {
case storage::kFileSystemTypeNativeLocal:
return GetLocalThumbnail(chrome_details, file_system_url,
params->crop_to_square);
case storage::kFileSystemTypeDriveFs:
return GetDrivefsThumbnail(chrome_details, file_system_url,
params->crop_to_square);
default:
return RespondNow(Error(base::StringPrintf(
"Unsupported file system type: %d", file_system_url.type())));
}
}
ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetThumbnailFunction::GetLocalThumbnail(
const ChromeExtensionFunctionDetails& chrome_details,
const storage::FileSystemURL& url,
bool crop_to_square) {
base::FilePath path = file_manager::util::GetLocalPathFromURL(
render_frame_host(), chrome_details.GetProfile(), url.ToGURL());
if (path.empty() ||
base::FilePath::CompareIgnoreCase(path.Extension(), ".pdf") != 0) {
return RespondNow(Error("Can only handle PDF files"));
}
return RespondNow(Error("Not implemented"));
}
ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetThumbnailFunction::GetDrivefsThumbnail(
const ChromeExtensionFunctionDetails& chrome_details,
const storage::FileSystemURL& url,
bool crop_to_square) {
// If the thumbnail is generated by drivefs give it a bit more time
// before issuing warnings about slow operation.
SetWarningThresholds(base::TimeDelta::FromSeconds(5),
base::TimeDelta::FromMinutes(1));
if (url.type() != storage::kFileSystemTypeDriveFs) {
return RespondNow(Error("Invalid URL"));
}
auto* drive_integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(
chrome_details.GetProfile());
if (!drive_integration_service) {
return RespondNow(Error("Drive service not available"));
}
base::FilePath path;
if (!drive_integration_service->GetRelativeDrivePath(url.path(), &path)) {
return RespondNow(Error("File not found"));
}
auto* drivefs_interface = drive_integration_service->GetDriveFsInterface();
if (!drivefs_interface) {
return RespondNow(Error("Drivefs not available"));
}
drivefs_interface->GetThumbnail(
path, crop_to_square,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(
&FileManagerPrivateInternalGetThumbnailFunction::GotThumbnail,
this),
base::Optional<std::vector<uint8_t>>()));
return RespondLater();
}
void FileManagerPrivateInternalGetThumbnailFunction::GotThumbnail(
const base::Optional<std::vector<uint8_t>>& data) {
if (!data) {
Respond(OneArgument(std::make_unique<base::Value>("")));
return;
}
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, base::BindOnce(&MakeThumbnailDataUrlOnThreadPool, *data),
base::BindOnce(
&FileManagerPrivateInternalGetThumbnailFunction::SendEncodedThumbnail,
this));
}
void FileManagerPrivateInternalGetThumbnailFunction::SendEncodedThumbnail(
std::string thumbnail_data_url) {
Respond(OneArgument(
std::make_unique<base::Value>(std::move(thumbnail_data_url))));
}
} // namespace extensions } // namespace extensions
...@@ -460,6 +460,48 @@ class FileManagerPrivateDetectCharacterEncodingFunction ...@@ -460,6 +460,48 @@ class FileManagerPrivateDetectCharacterEncodingFunction
ResponseAction Run() override; ResponseAction Run() override;
}; };
class FileManagerPrivateInternalGetThumbnailFunction
: public LoggedExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getThumbnail",
FILEMANAGERPRIVATEINTERNAL_GETTHUMBNAIL)
FileManagerPrivateInternalGetThumbnailFunction();
protected:
~FileManagerPrivateInternalGetThumbnailFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
private:
// Attempts to generate a thumbnail for the given url. This method
// checks that the URL references a Google Drive file.
ResponseAction GetDrivefsThumbnail(
const ChromeExtensionFunctionDetails& chrome_details,
const storage::FileSystemURL& url,
bool crop_to_square);
// Attempts to generate a thumbnail for the given url. This method checks
// that the URL references a local PDF file. If so, it attempts to generate
// a one page thumbnail.
ResponseAction GetLocalThumbnail(
const ChromeExtensionFunctionDetails& chrome_details,
const storage::FileSystemURL& url,
bool crop_to_square);
// A function that performs IO operations to read and render PDF thumbnail
// Must be run on the IO Thread.
void GetLocalThumbnailOnIOThread(const base::FilePath& path,
bool crop_to_square);
// A callback invoked when thumbnail data has been generated.
void GotThumbnail(const base::Optional<std::vector<uint8_t>>& data);
// Responds with a base64 encoded PNG thumbnail data.
void SendEncodedThumbnail(std::string thumbnail_data_url);
};
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_MISC_H_ #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_MISC_H_
...@@ -1186,7 +1186,7 @@ interface Functions { ...@@ -1186,7 +1186,7 @@ interface Functions {
[nocompile] [nocompile]
static void importCrostiniImage([instanceof=Entry] object entry); static void importCrostiniImage([instanceof=Entry] object entry);
// For a file in DriveFS, retrieves its thumbnail. If |cropToSquare| is true, // For a given file entry, retrieves its thumbnail. If |cropToSquare| is true,
// returns a thumbnail appropriate for file list or grid views; otherwise, // returns a thumbnail appropriate for file list or grid views; otherwise,
// returns a thumbnail appropriate for quickview. // returns a thumbnail appropriate for quickview.
[nocompile] [nocompile]
......
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