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

Side by Side Diff: content/renderer/webclipboard_impl.cc

Issue 574273002: Rewrite clipboard write IPC handling to be easier to understand. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Document Created 6 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « content/renderer/webclipboard_impl.h ('k') | ui/base/clipboard/clipboard.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/webclipboard_impl.h" 5 #include "content/renderer/webclipboard_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/pickle.h"
9 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
11 #include "content/common/clipboard_format.h" 10 #include "content/common/clipboard_format.h"
12 #include "content/public/common/drop_data.h" 11 #include "content/public/common/drop_data.h"
13 #include "content/renderer/clipboard_utils.h" 12 #include "content/renderer/clipboard_utils.h"
14 #include "content/renderer/drop_data_builder.h" 13 #include "content/renderer/drop_data_builder.h"
15 #include "content/renderer/scoped_clipboard_writer_glue.h" 14 #include "content/renderer/renderer_clipboard_delegate.h"
16 #include "third_party/WebKit/public/platform/WebData.h" 15 #include "third_party/WebKit/public/platform/WebData.h"
17 #include "third_party/WebKit/public/platform/WebDragData.h" 16 #include "third_party/WebKit/public/platform/WebDragData.h"
18 #include "third_party/WebKit/public/platform/WebImage.h" 17 #include "third_party/WebKit/public/platform/WebImage.h"
19 #include "third_party/WebKit/public/platform/WebSize.h" 18 #include "third_party/WebKit/public/platform/WebSize.h"
20 #include "third_party/WebKit/public/platform/WebString.h" 19 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/platform/WebURL.h" 20 #include "third_party/WebKit/public/platform/WebURL.h"
22 #include "third_party/WebKit/public/platform/WebVector.h" 21 #include "third_party/WebKit/public/platform/WebVector.h"
23 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "ui/base/clipboard/clipboard.h"
25 #include "ui/base/clipboard/custom_data_helper.h"
26 #include "url/gurl.h" 22 #include "url/gurl.h"
27 23
28 using blink::WebClipboard; 24 using blink::WebClipboard;
29 using blink::WebData; 25 using blink::WebData;
30 using blink::WebDragData; 26 using blink::WebDragData;
31 using blink::WebImage; 27 using blink::WebImage;
32 using blink::WebString; 28 using blink::WebString;
33 using blink::WebURL; 29 using blink::WebURL;
34 using blink::WebVector; 30 using blink::WebVector;
35 31
36 namespace content { 32 namespace content {
37 33
38 WebClipboardImpl::WebClipboardImpl(ClipboardClient* client) 34 WebClipboardImpl::WebClipboardImpl(RendererClipboardDelegate* delegate)
39 : client_(client) { 35 : delegate_(delegate) {
36 DCHECK(delegate);
40 } 37 }
41 38
42 WebClipboardImpl::~WebClipboardImpl() { 39 WebClipboardImpl::~WebClipboardImpl() {
43 } 40 }
44 41
45 uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) { 42 uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
46 ui::ClipboardType clipboard_type; 43 ui::ClipboardType clipboard_type;
47 if (!ConvertBufferType(buffer, &clipboard_type)) 44 if (!ConvertBufferType(buffer, &clipboard_type))
48 return 0; 45 return 0;
49 46
50 return client_->GetSequenceNumber(clipboard_type); 47 return delegate_->GetSequenceNumber(clipboard_type);
51 } 48 }
52 49
53 bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) { 50 bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
54 ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE; 51 ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE;
55 52
56 if (!ConvertBufferType(buffer, &clipboard_type)) 53 if (!ConvertBufferType(buffer, &clipboard_type))
57 return false; 54 return false;
58 55
59 switch (format) { 56 switch (format) {
60 case FormatPlainText: 57 case FormatPlainText:
61 return client_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT, 58 return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT,
62 clipboard_type); 59 clipboard_type);
63 case FormatHTML: 60 case FormatHTML:
64 return client_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML, clipboard_type); 61 return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML,
62 clipboard_type);
65 case FormatSmartPaste: 63 case FormatSmartPaste:
66 return client_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE, 64 return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE,
67 clipboard_type); 65 clipboard_type);
68 case FormatBookmark: 66 case FormatBookmark:
69 return client_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK, 67 return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK,
70 clipboard_type); 68 clipboard_type);
71 default: 69 default:
72 NOTREACHED(); 70 NOTREACHED();
73 } 71 }
74 72
75 return false; 73 return false;
76 } 74 }
77 75
78 WebVector<WebString> WebClipboardImpl::readAvailableTypes( 76 WebVector<WebString> WebClipboardImpl::readAvailableTypes(
79 Buffer buffer, bool* contains_filenames) { 77 Buffer buffer, bool* contains_filenames) {
80 ui::ClipboardType clipboard_type; 78 ui::ClipboardType clipboard_type;
81 std::vector<base::string16> types; 79 std::vector<base::string16> types;
82 if (ConvertBufferType(buffer, &clipboard_type)) { 80 if (ConvertBufferType(buffer, &clipboard_type)) {
83 client_->ReadAvailableTypes(clipboard_type, &types, contains_filenames); 81 delegate_->ReadAvailableTypes(clipboard_type, &types, contains_filenames);
84 } 82 }
85 return types; 83 return types;
86 } 84 }
87 85
88 WebString WebClipboardImpl::readPlainText(Buffer buffer) { 86 WebString WebClipboardImpl::readPlainText(Buffer buffer) {
89 ui::ClipboardType clipboard_type; 87 ui::ClipboardType clipboard_type;
90 if (!ConvertBufferType(buffer, &clipboard_type)) 88 if (!ConvertBufferType(buffer, &clipboard_type))
91 return WebString(); 89 return WebString();
92 90
93 base::string16 text; 91 base::string16 text;
94 client_->ReadText(clipboard_type, &text); 92 delegate_->ReadText(clipboard_type, &text);
95 return text; 93 return text;
96 } 94 }
97 95
98 WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url, 96 WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
99 unsigned* fragment_start, 97 unsigned* fragment_start,
100 unsigned* fragment_end) { 98 unsigned* fragment_end) {
101 ui::ClipboardType clipboard_type; 99 ui::ClipboardType clipboard_type;
102 if (!ConvertBufferType(buffer, &clipboard_type)) 100 if (!ConvertBufferType(buffer, &clipboard_type))
103 return WebString(); 101 return WebString();
104 102
105 base::string16 html_stdstr; 103 base::string16 html_stdstr;
106 GURL gurl; 104 GURL gurl;
107 client_->ReadHTML(clipboard_type, &html_stdstr, &gurl, 105 delegate_->ReadHTML(clipboard_type,
108 static_cast<uint32*>(fragment_start), 106 &html_stdstr,
109 static_cast<uint32*>(fragment_end)); 107 &gurl,
108 static_cast<uint32*>(fragment_start),
109 static_cast<uint32*>(fragment_end));
110 *source_url = gurl; 110 *source_url = gurl;
111 return html_stdstr; 111 return html_stdstr;
112 } 112 }
113 113
114 WebData WebClipboardImpl::readImage(Buffer buffer) { 114 WebData WebClipboardImpl::readImage(Buffer buffer) {
115 ui::ClipboardType clipboard_type; 115 ui::ClipboardType clipboard_type;
116 if (!ConvertBufferType(buffer, &clipboard_type)) 116 if (!ConvertBufferType(buffer, &clipboard_type))
117 return WebData(); 117 return WebData();
118 118
119 std::string png_data; 119 std::string png_data;
120 client_->ReadImage(clipboard_type, &png_data); 120 delegate_->ReadImage(clipboard_type, &png_data);
121 return WebData(png_data); 121 return WebData(png_data);
122 } 122 }
123 123
124 WebString WebClipboardImpl::readCustomData(Buffer buffer, 124 WebString WebClipboardImpl::readCustomData(Buffer buffer,
125 const WebString& type) { 125 const WebString& type) {
126 ui::ClipboardType clipboard_type; 126 ui::ClipboardType clipboard_type;
127 if (!ConvertBufferType(buffer, &clipboard_type)) 127 if (!ConvertBufferType(buffer, &clipboard_type))
128 return WebString(); 128 return WebString();
129 129
130 base::string16 data; 130 base::string16 data;
131 client_->ReadCustomData(clipboard_type, type, &data); 131 delegate_->ReadCustomData(clipboard_type, type, &data);
132 return data; 132 return data;
133 } 133 }
134 134
135 void WebClipboardImpl::writePlainText(const WebString& plain_text) { 135 void WebClipboardImpl::writePlainText(const WebString& plain_text) {
136 ScopedClipboardWriterGlue scw(client_); 136 delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text);
137 scw.WriteText(plain_text); 137 delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
138 } 138 }
139 139
140 void WebClipboardImpl::writeHTML( 140 void WebClipboardImpl::writeHTML(
141 const WebString& html_text, const WebURL& source_url, 141 const WebString& html_text, const WebURL& source_url,
142 const WebString& plain_text, bool write_smart_paste) { 142 const WebString& plain_text, bool write_smart_paste) {
143 ScopedClipboardWriterGlue scw(client_); 143 delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, html_text, source_url);
144 scw.WriteHTML(html_text, source_url.spec()); 144 delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text);
145 scw.WriteText(plain_text);
146 145
147 if (write_smart_paste) 146 if (write_smart_paste)
148 scw.WriteWebSmartPaste(); 147 delegate_->WriteSmartPasteMarker(ui::CLIPBOARD_TYPE_COPY_PASTE);
148 delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
149 } 149 }
150 150
151 void WebClipboardImpl::writeImage(const WebImage& image, 151 void WebClipboardImpl::writeImage(const WebImage& image,
152 const WebURL& url, 152 const WebURL& url,
153 const WebString& title) { 153 const WebString& title) {
154 ScopedClipboardWriterGlue scw(client_); 154 DCHECK(!image.isNull());
155 155 const SkBitmap& bitmap = image.getSkBitmap();
156 if (!image.isNull()) { 156 if (!delegate_->WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap))
157 const SkBitmap& bitmap = image.getSkBitmap(); 157 return;
158 // WriteBitmapFromPixels expects 32-bit data.
159 DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
160
161 SkAutoLockPixels locked(bitmap);
162 void *pixels = bitmap.getPixels();
163 // TODO(piman): this should not be NULL, but it is. crbug.com/369621
164 if (!pixels)
165 return;
166 scw.WriteBitmapFromPixels(pixels, image.size());
167 }
168 158
169 if (!url.isEmpty()) { 159 if (!url.isEmpty()) {
170 scw.WriteBookmark(title, url.spec()); 160 delegate_->WriteBookmark(ui::CLIPBOARD_TYPE_COPY_PASTE, url, title);
171 #if !defined(OS_MACOSX) 161 #if !defined(OS_MACOSX)
172 // When writing the image, we also write the image markup so that pasting 162 // When writing the image, we also write the image markup so that pasting
173 // into rich text editors, such as Gmail, reveals the image. We also don't 163 // into rich text editors, such as Gmail, reveals the image. We also don't
174 // want to call writeText(), since some applications (WordPad) don't pick 164 // want to call writeText(), since some applications (WordPad) don't pick
175 // the image if there is also a text format on the clipboard. 165 // the image if there is also a text format on the clipboard.
176 // We also don't want to write HTML on a Mac, since Mail.app prefers to use 166 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
177 // the image markup over attaching the actual image. See 167 // the image markup over attaching the actual image. See
178 // http://crbug.com/33016 for details. 168 // http://crbug.com/33016 for details.
179 scw.WriteHTML(base::UTF8ToUTF16(URLToImageMarkup(url, title)), 169 delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE,
180 std::string()); 170 base::UTF8ToUTF16(URLToImageMarkup(url, title)),
171 GURL());
181 #endif 172 #endif
182 } 173 }
174 delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
183 } 175 }
184 176
185 void WebClipboardImpl::writeDataObject(const WebDragData& data) { 177 void WebClipboardImpl::writeDataObject(const WebDragData& data) {
186 ScopedClipboardWriterGlue scw(client_);
187
188 const DropData& data_object = DropDataBuilder::Build(data); 178 const DropData& data_object = DropDataBuilder::Build(data);
189 // TODO(dcheng): Properly support text/uri-list here. 179 // TODO(dcheng): Properly support text/uri-list here.
180 // Avoid calling the WriteFoo functions if there is no data associated with a
181 // type. This prevents stomping on clipboard contents that might have been
182 // written by extension functions such as chrome.bookmarkManagerPrivate.copy.
190 if (!data_object.text.is_null()) 183 if (!data_object.text.is_null())
191 scw.WriteText(data_object.text.string()); 184 delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE,
185 data_object.text.string());
192 if (!data_object.html.is_null()) 186 if (!data_object.html.is_null())
193 scw.WriteHTML(data_object.html.string(), std::string()); 187 delegate_->WriteHTML(
194 // If there is no custom data, avoid calling WritePickledData. This ensures 188 ui::CLIPBOARD_TYPE_COPY_PASTE, data_object.html.string(), GURL());
195 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't 189 if (!data_object.custom_data.empty())
196 // modify the DataTransfer object, which is important to avoid stomping on 190 delegate_->WriteCustomData(ui::CLIPBOARD_TYPE_COPY_PASTE,
197 // any clipboard contents written by extension functions such as 191 data_object.custom_data);
198 // chrome.bookmarkManagerPrivate.copy. 192 delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
199 if (!data_object.custom_data.empty()) {
200 Pickle pickle;
201 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
202 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
203 }
204 } 193 }
205 194
206 bool WebClipboardImpl::ConvertBufferType(Buffer buffer, 195 bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
207 ui::ClipboardType* result) { 196 ui::ClipboardType* result) {
208 *result = ui::CLIPBOARD_TYPE_COPY_PASTE; 197 *result = ui::CLIPBOARD_TYPE_COPY_PASTE;
209 switch (buffer) { 198 switch (buffer) {
210 case BufferStandard: 199 case BufferStandard:
211 break; 200 break;
212 case BufferSelection: 201 case BufferSelection:
213 #if defined(USE_X11) && !defined(OS_CHROMEOS) 202 #if defined(USE_X11) && !defined(OS_CHROMEOS)
214 *result = ui::CLIPBOARD_TYPE_SELECTION; 203 *result = ui::CLIPBOARD_TYPE_SELECTION;
215 break; 204 break;
216 #else 205 #else
217 // Chrome OS and non-X11 unix builds do not support 206 // Chrome OS and non-X11 unix builds do not support
218 // the X selection clipboad. 207 // the X selection clipboad.
219 // TODO: remove the need for this case, see http://crbug.com/361753 208 // TODO: remove the need for this case, see http://crbug.com/361753
220 return false; 209 return false;
221 #endif 210 #endif
222 default: 211 default:
223 NOTREACHED(); 212 NOTREACHED();
224 return false; 213 return false;
225 } 214 }
226 return true; 215 return true;
227 } 216 }
228 217
229 } // namespace content 218 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/webclipboard_impl.h ('k') | ui/base/clipboard/clipboard.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698