Commit be6804f2 authored by Bo Majewski's avatar Bo Majewski Committed by Commit Bot

Files App: Encode thumbnails on a non-UI thread.

Bug: 1129607
Change-Id: I32cf4c9f0c19ae310a2de7d449dcbd783651291d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2417790
Commit-Queue: Bo Majewski <majewski@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809110}
parent 470c95ab
...@@ -211,6 +211,22 @@ std::string MakeThumbnailDataUrlOnThreadPool( ...@@ -211,6 +211,22 @@ std::string MakeThumbnailDataUrlOnThreadPool(
return base::StrCat({"data:image/png;base64,", base::Base64Encode(png_data)}); return base::StrCat({"data:image/png;base64,", base::Base64Encode(png_data)});
} }
// Converts bitmap to a PNG image and encodes it as a data string.
std::string ConvertAndEncode(const SkBitmap& bitmap) {
if (bitmap.isNull()) {
DLOG(WARNING) << "Got an invalid bitmap";
return std::string();
}
sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
sk_sp<SkData> png_data(image->encodeToData(SkEncodedImageFormat::kPNG, 100));
if (!png_data) {
DLOG(WARNING) << "Thumbnail encoding error";
return std::string();
}
return MakeThumbnailDataUrlOnThreadPool(base::make_span(
reinterpret_cast<const uint8_t*>(png_data->data()), png_data->size()));
}
// The maximum size of the input PDF file for which thumbnails are generated. // The maximum size of the input PDF file for which thumbnails are generated.
constexpr uint32_t kMaxPdfSize = 1024u * 1024u; constexpr uint32_t kMaxPdfSize = 1024u * 1024u;
...@@ -1191,7 +1207,8 @@ FileManagerPrivateInternalGetThumbnailFunction::GetLocalThumbnail( ...@@ -1191,7 +1207,8 @@ FileManagerPrivateInternalGetThumbnailFunction::GetLocalThumbnail(
return RespondNow(Error("Can only handle PDF files")); return RespondNow(Error("Can only handle PDF files"));
} }
base::ThreadPool::PostTaskAndReplyWithResult( base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&ReadLocalPdf, path), FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
base::BindOnce(&ReadLocalPdf, path),
base::BindOnce( base::BindOnce(
&FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail, &FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail,
this, crop_to_square)); this, crop_to_square));
...@@ -1200,9 +1217,10 @@ FileManagerPrivateInternalGetThumbnailFunction::GetLocalThumbnail( ...@@ -1200,9 +1217,10 @@ FileManagerPrivateInternalGetThumbnailFunction::GetLocalThumbnail(
void FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail( void FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail(
bool crop_to_square, bool crop_to_square,
const std::string& pdf_contents) { const std::string& contents) {
if (pdf_contents.empty()) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Respond(Error("Failed to read file content")); if (contents.empty()) {
Respond(Error("Failed to read PDF file"));
return; return;
} }
if (!pdf_thumbnailer_.is_bound()) { if (!pdf_thumbnailer_.is_bound()) {
...@@ -1213,9 +1231,8 @@ void FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail( ...@@ -1213,9 +1231,8 @@ void FileManagerPrivateInternalGetThumbnailFunction::FetchPdfThumbnail(
PdfThumbnailDisconected, PdfThumbnailDisconected,
base::Unretained(this))); base::Unretained(this)));
} }
auto pdf_region = auto pdf_region = base::ReadOnlySharedMemoryRegion::Create(contents.size());
base::ReadOnlySharedMemoryRegion::Create(pdf_contents.size()); memcpy(pdf_region.mapping.memory(), contents.data(), contents.size());
memcpy(pdf_region.mapping.memory(), pdf_contents.data(), pdf_contents.size());
gfx::Size thumb_size = gfx::Size thumb_size =
crop_to_square crop_to_square
? gfx::Size(FileManagerPrivateInternalGetThumbnailFunction::kSize, ? gfx::Size(FileManagerPrivateInternalGetThumbnailFunction::kSize,
...@@ -1241,18 +1258,12 @@ void FileManagerPrivateInternalGetThumbnailFunction::PdfThumbnailDisconected() { ...@@ -1241,18 +1258,12 @@ void FileManagerPrivateInternalGetThumbnailFunction::PdfThumbnailDisconected() {
void FileManagerPrivateInternalGetThumbnailFunction::GotPdfThumbnail( void FileManagerPrivateInternalGetThumbnailFunction::GotPdfThumbnail(
const SkBitmap& bitmap) { const SkBitmap& bitmap) {
if (bitmap.isNull()) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Respond(Error("Failed to render the thumbnail")); base::ThreadPool::PostTaskAndReplyWithResult(
return; FROM_HERE, base::BindOnce(&ConvertAndEncode, bitmap),
} base::BindOnce(
sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); &FileManagerPrivateInternalGetThumbnailFunction::SendEncodedThumbnail,
sk_sp<SkData> png_data(image->encodeToData(SkEncodedImageFormat::kPNG, 100)); this));
if (!png_data) {
Respond(Error("Thumbnail encoding error"));
return;
}
SendEncodedThumbnail(MakeThumbnailDataUrlOnThreadPool(base::make_span(
reinterpret_cast<const uint8_t*>(png_data->data()), png_data->size())));
} }
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
......
...@@ -546,10 +546,10 @@ class FileManagerPrivateInternalGetThumbnailFunction ...@@ -546,10 +546,10 @@ class FileManagerPrivateInternalGetThumbnailFunction
const storage::FileSystemURL& url, const storage::FileSystemURL& url,
bool crop_to_square); bool crop_to_square);
// For a given |pdf_contents| starts fetching the first page PDF thumbnail by // For a given |content| starts fetching the first page PDF thumbnail by
// calling PdfThumbnailer from the printing service. The first parameter, // calling PdfThumbnailer from the printing service. The first parameter,
// |crop_to_square| is supplied by the JavaScript caller. // |crop_to_square| is supplied by the JavaScript caller.
void FetchPdfThumbnail(bool crop_to_square, const std::string& pdf_contents); void FetchPdfThumbnail(bool crop_to_square, const std::string& content);
// Callback invoked by the thumbnailing service when a PDF thumbnail has been // Callback invoked by the thumbnailing service when a PDF thumbnail has been
// generated. The solitary parameter |bitmap| is supplied by the callback. // generated. The solitary parameter |bitmap| is supplied by the 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