summaryrefslogtreecommitdiffstats
path: root/content/renderer/webclipboard_impl.cc
diff options
context:
space:
mode:
authordcheng <dcheng@chromium.org>2014-11-19 23:16:49 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-20 07:17:08 +0000
commit112adc89f9665f2fd37c1882e1619d183dbbcea0 (patch)
treee9405efba87b9f6da0a49cac9f9e546e261341d6 /content/renderer/webclipboard_impl.cc
parent9196d87fcce71cbc79c5c0bb660dc6b0a9d0c670 (diff)
downloadchromium_src-112adc89f9665f2fd37c1882e1619d183dbbcea0.zip
chromium_src-112adc89f9665f2fd37c1882e1619d183dbbcea0.tar.gz
chromium_src-112adc89f9665f2fd37c1882e1619d183dbbcea0.tar.bz2
Reland rewrite clipboard write IPC handling to be easier to understand.
The original implementation sent clipboard data to be written over IPC as a map of clipboard formats to 'parameters' for that format. The parameters were just vectors of byte vectors. Needless to say, this logic was complicated, fragile, and prone to bugs. In the browser process, this resulted in the IPC validation logic being scattered between ClipboardMessageFilter and Clipboard::DispatchObject. The rewrite adds an IPC message for each flavor of data that the renderer is allowed to write to the clipboard. On the browser side, the logic is simply delegated to ScopedClipboardWriter. Since the clipboard object map is no longer under the control of an untrusted process, this allows the removal of a lot of validation logic. Unfortunately, bitmap handling is still a bit complicated because it's sent over shared memory, but all the validation logic has been moved into ClipboardMessageFilter. BUG=319285 TBR=avi@chromium.org,jamesr@chromium.org,wfh@chromium.org Review URL: https://codereview.chromium.org/740763003 Cr-Commit-Position: refs/heads/master@{#304988}
Diffstat (limited to 'content/renderer/webclipboard_impl.cc')
-rw-r--r--content/renderer/webclipboard_impl.cc105
1 files changed, 46 insertions, 59 deletions
diff --git a/content/renderer/webclipboard_impl.cc b/content/renderer/webclipboard_impl.cc
index e248c51..19f2362 100644
--- a/content/renderer/webclipboard_impl.cc
+++ b/content/renderer/webclipboard_impl.cc
@@ -5,14 +5,13 @@
#include "content/renderer/webclipboard_impl.h"
#include "base/logging.h"
-#include "base/pickle.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/clipboard_format.h"
#include "content/public/common/drop_data.h"
#include "content/renderer/clipboard_utils.h"
#include "content/renderer/drop_data_builder.h"
-#include "content/renderer/scoped_clipboard_writer_glue.h"
+#include "content/renderer/renderer_clipboard_delegate.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebDragData.h"
#include "third_party/WebKit/public/platform/WebImage.h"
@@ -20,9 +19,6 @@
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/WebVector.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/base/clipboard/custom_data_helper.h"
#include "url/gurl.h"
using blink::WebClipboard;
@@ -35,8 +31,9 @@ using blink::WebVector;
namespace content {
-WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
- : client_(client) {
+WebClipboardImpl::WebClipboardImpl(RendererClipboardDelegate* delegate)
+ : delegate_(delegate) {
+ DCHECK(delegate);
}
WebClipboardImpl::~WebClipboardImpl() {
@@ -47,7 +44,7 @@ uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
if (!ConvertBufferType(buffer, &clipboard_type))
return 0;
- return client_->GetSequenceNumber(clipboard_type);
+ return delegate_->GetSequenceNumber(clipboard_type);
}
bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
@@ -58,16 +55,17 @@ bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
switch (format) {
case FormatPlainText:
- return client_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT,
- clipboard_type);
+ return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT,
+ clipboard_type);
case FormatHTML:
- return client_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML, clipboard_type);
+ return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML,
+ clipboard_type);
case FormatSmartPaste:
- return client_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE,
- clipboard_type);
+ return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE,
+ clipboard_type);
case FormatBookmark:
- return client_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK,
- clipboard_type);
+ return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK,
+ clipboard_type);
default:
NOTREACHED();
}
@@ -80,7 +78,7 @@ WebVector<WebString> WebClipboardImpl::readAvailableTypes(
ui::ClipboardType clipboard_type;
std::vector<base::string16> types;
if (ConvertBufferType(buffer, &clipboard_type)) {
- client_->ReadAvailableTypes(clipboard_type, &types, contains_filenames);
+ delegate_->ReadAvailableTypes(clipboard_type, &types, contains_filenames);
}
return types;
}
@@ -91,7 +89,7 @@ WebString WebClipboardImpl::readPlainText(Buffer buffer) {
return WebString();
base::string16 text;
- client_->ReadText(clipboard_type, &text);
+ delegate_->ReadText(clipboard_type, &text);
return text;
}
@@ -104,9 +102,9 @@ WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
base::string16 html_stdstr;
GURL gurl;
- client_->ReadHTML(clipboard_type, &html_stdstr, &gurl,
- static_cast<uint32*>(fragment_start),
- static_cast<uint32*>(fragment_end));
+ delegate_->ReadHTML(clipboard_type, &html_stdstr, &gurl,
+ static_cast<uint32*>(fragment_start),
+ static_cast<uint32*>(fragment_end));
*source_url = gurl;
return html_stdstr;
}
@@ -117,7 +115,7 @@ WebData WebClipboardImpl::readImage(Buffer buffer) {
return WebData();
std::string png_data;
- client_->ReadImage(clipboard_type, &png_data);
+ delegate_->ReadImage(clipboard_type, &png_data);
return WebData(png_data);
}
@@ -128,46 +126,36 @@ WebString WebClipboardImpl::readCustomData(Buffer buffer,
return WebString();
base::string16 data;
- client_->ReadCustomData(clipboard_type, type, &data);
+ delegate_->ReadCustomData(clipboard_type, type, &data);
return data;
}
void WebClipboardImpl::writePlainText(const WebString& plain_text) {
- ScopedClipboardWriterGlue scw(client_);
- scw.WriteText(plain_text);
+ delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text);
+ delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::writeHTML(
const WebString& html_text, const WebURL& source_url,
const WebString& plain_text, bool write_smart_paste) {
- ScopedClipboardWriterGlue scw(client_);
- scw.WriteHTML(html_text, source_url.spec());
- scw.WriteText(plain_text);
+ delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, html_text, source_url);
+ delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text);
if (write_smart_paste)
- scw.WriteWebSmartPaste();
+ delegate_->WriteSmartPasteMarker(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::writeImage(const WebImage& image,
const WebURL& url,
const WebString& title) {
- ScopedClipboardWriterGlue scw(client_);
-
- if (!image.isNull()) {
- const SkBitmap& bitmap = image.getSkBitmap();
- // WriteBitmapFromPixels expects 32-bit data.
- DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
-
- SkAutoLockPixels locked(bitmap);
- void *pixels = bitmap.getPixels();
- // TODO(piman): this should not be NULL, but it is. crbug.com/369621
- if (!pixels)
- return;
- scw.WriteBitmapFromPixels(pixels, image.size());
- }
+ DCHECK(!image.isNull());
+ const SkBitmap& bitmap = image.getSkBitmap();
+ if (!delegate_->WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap))
+ return;
if (!url.isEmpty()) {
- scw.WriteBookmark(title, url.spec());
+ delegate_->WriteBookmark(ui::CLIPBOARD_TYPE_COPY_PASTE, url, title);
#if !defined(OS_MACOSX)
// When writing the image, we also write the image markup so that pasting
// into rich text editors, such as Gmail, reveals the image. We also don't
@@ -176,31 +164,30 @@ void WebClipboardImpl::writeImage(const WebImage& image,
// We also don't want to write HTML on a Mac, since Mail.app prefers to use
// the image markup over attaching the actual image. See
// http://crbug.com/33016 for details.
- scw.WriteHTML(base::UTF8ToUTF16(URLToImageMarkup(url, title)),
- std::string());
+ delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ base::UTF8ToUTF16(URLToImageMarkup(url, title)),
+ GURL());
#endif
}
+ delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::writeDataObject(const WebDragData& data) {
- ScopedClipboardWriterGlue scw(client_);
-
const DropData& data_object = DropDataBuilder::Build(data);
// TODO(dcheng): Properly support text/uri-list here.
+ // Avoid calling the WriteFoo functions if there is no data associated with a
+ // type. This prevents stomping on clipboard contents that might have been
+ // written by extension functions such as chrome.bookmarkManagerPrivate.copy.
if (!data_object.text.is_null())
- scw.WriteText(data_object.text.string());
+ delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ data_object.text.string());
if (!data_object.html.is_null())
- scw.WriteHTML(data_object.html.string(), std::string());
- // If there is no custom data, avoid calling WritePickledData. This ensures
- // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
- // modify the DataTransfer object, which is important to avoid stomping on
- // any clipboard contents written by extension functions such as
- // chrome.bookmarkManagerPrivate.copy.
- if (!data_object.custom_data.empty()) {
- Pickle pickle;
- ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
- scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
- }
+ delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ data_object.html.string(), GURL());
+ if (!data_object.custom_data.empty())
+ delegate_->WriteCustomData(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ data_object.custom_data);
+ delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
bool WebClipboardImpl::ConvertBufferType(Buffer buffer,