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

Unified Diff: content/browser/renderer_host/clipboard_message_filter.cc

Issue 1876653003: Register clipboard image blob in the browser process to copy data less. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 8 months 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: content/browser/renderer_host/clipboard_message_filter.cc
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc
index 7e46a30d7714faba804ad94e7e13cf3fcd561e47..e317c9e81beccc0dcd4131765ce5eef17ab5ce64 100644
--- a/content/browser/renderer_host/clipboard_message_filter.cc
+++ b/content/browser/renderer_host/clipboard_message_filter.cc
@@ -4,7 +4,7 @@
#include "content/browser/renderer_host/clipboard_message_filter.h"
-#include <memory>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -12,11 +12,16 @@
#include "base/macros.h"
#include "base/pickle.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "build/build_config.h"
+#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/common/clipboard_messages.h"
+#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/codec/png_codec.h"
@@ -31,13 +36,18 @@ void ReleaseSharedMemoryPixels(void* addr, void* context) {
delete reinterpret_cast<base::SharedMemory*>(context);
}
+// No-op helper for delayed cleanup of BlobHandles generated by reading
+// clipboard images.
+void CleanupReadImageBlob(std::unique_ptr<content::BlobHandle>) {}
+
} // namespace
-ClipboardMessageFilter::ClipboardMessageFilter()
+ClipboardMessageFilter::ClipboardMessageFilter(
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
: BrowserMessageFilter(ClipboardMsgStart),
+ blob_storage_context_(std::move(blob_storage_context)),
clipboard_writer_(
- new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {
-}
+ new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}
void ClipboardMessageFilter::OverrideThreadForMessage(
const IPC::Message& message, BrowserThread::ID* thread) {
@@ -54,11 +64,6 @@ void ClipboardMessageFilter::OverrideThreadForMessage(
if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
*thread = BrowserThread::UI;
#endif
-
-#if defined(OS_WIN)
- if (message.type() == ClipboardHostMsg_ReadImage::ID)
- *thread = BrowserThread::FILE;
-#endif
}
bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message) {
@@ -175,34 +180,58 @@ void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type,
IPC::Message* reply_msg) {
SkBitmap bitmap = GetClipboard()->ReadImage(type);
-#if defined(USE_X11)
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(
- &ClipboardMessageFilter::OnReadImageReply, this, bitmap, reply_msg));
-#else
- OnReadImageReply(bitmap, reply_msg);
-#endif
+ BrowserThread::GetBlockingPool()
+ ->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)
+ ->PostTask(FROM_HERE,
+ base::Bind(&ClipboardMessageFilter::ReadAndEncodeImage, this,
+ bitmap, reply_msg));
}
-void ClipboardMessageFilter::OnReadImageReply(
- const SkBitmap& bitmap, IPC::Message* reply_msg) {
- base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle();
- uint32_t image_size = 0;
+void ClipboardMessageFilter::ReadAndEncodeImage(const SkBitmap& bitmap,
+ IPC::Message* reply_msg) {
if (!bitmap.isNull()) {
- std::vector<unsigned char> png_data;
- if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
- base::SharedMemory buffer;
- if (buffer.CreateAndMapAnonymous(png_data.size())) {
- memcpy(buffer.memory(), png_data.data(), png_data.size());
- if (buffer.GiveToProcess(PeerHandle(), &image_handle)) {
- image_size = png_data.size();
- }
- }
+ std::unique_ptr<std::vector<uint8_t>> png_data(new std::vector<uint8_t>);
+ if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, png_data.get())) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClipboardMessageFilter::OnReadAndEncodeImageFinished,
+ this, base::Passed(&png_data), reply_msg));
+ return;
+ }
+ }
+ ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, std::string(),
+ std::string(), -1);
+ Send(reply_msg);
+}
+
+void ClipboardMessageFilter::OnReadAndEncodeImageFinished(
+ std::unique_ptr<std::vector<uint8_t>> png_data,
+ IPC::Message* reply_msg) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (png_data->size() < std::numeric_limits<uint32_t>::max()) {
+ std::unique_ptr<content::BlobHandle> blob_handle =
+ blob_storage_context_->CreateMemoryBackedBlob(
+ reinterpret_cast<char*>(png_data->data()), png_data->size());
+ if (blob_handle) {
+ ClipboardHostMsg_ReadImage::WriteReplyParams(
+ reply_msg, blob_handle->GetUUID(), ui::Clipboard::kMimeTypePNG,
+ static_cast<int64_t>(png_data->size()));
+ Send(reply_msg);
+ // Give the renderer a minute to pick up a reference to the blob before
+ // giving up.
+ // TODO(dmurph): There should be a better way of transferring ownership of
+ // a blob from the browser to the renderer, rather than relying on this
+ // timeout to clean up eventually. See https://crbug.com/604800.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CleanupReadImageBlob, base::Passed(&blob_handle)),
+ base::TimeDelta::FromMinutes(1));
+ return;
}
}
- ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle,
- image_size);
+ ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, std::string(),
+ std::string(), -1);
Send(reply_msg);
}

Powered by Google App Engine
This is Rietveld 408576698