1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/base/clipboard/clipboard_aura.h"
6 
7 #include <stdint.h>
8 
9 #include <limits>
10 #include <list>
11 #include <memory>
12 #include <utility>
13 
14 #include "base/files/file_path.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "base/memory/ptr_util.h"
18 #include "base/no_destructor.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "skia/ext/skia_utils_base.h"
21 #include "third_party/skia/include/core/SkBitmap.h"
22 #include "ui/base/clipboard/clipboard_constants.h"
23 #include "ui/base/clipboard/clipboard_format_type.h"
24 #include "ui/base/clipboard/clipboard_monitor.h"
25 #include "ui/base/clipboard/custom_data_helper.h"
26 #include "ui/gfx/geometry/size.h"
27 #include "ui/ozone/buildflags.h"
28 
29 namespace ui {
30 
31 namespace {
32 
33 const size_t kMaxClipboardSize = 1;
34 
35 // Clipboard data format used by AuraClipboard.
36 enum class AuraClipboardFormat {
37   kText = 1 << 0,
38   kHtml = 1 << 1,
39   kRtf = 1 << 2,
40   kBookmark = 1 << 3,
41   kBitmap = 1 << 4,
42   kCustom = 1 << 5,
43   kWeb = 1 << 6,
44 };
45 
46 // ClipboardData contains data copied to the Clipboard for a variety of formats.
47 // It mostly just provides APIs to cleanly access and manipulate this data.
48 class ClipboardData {
49  public:
ClipboardData()50   ClipboardData()
51       : web_smart_paste_(false),
52         format_(0) {}
53 
54   virtual ~ClipboardData() = default;
55 
56   // Bitmask of AuraClipboardFormat types.
format() const57   int format() const { return format_; }
58 
text() const59   const std::string& text() const { return text_; }
set_text(const std::string & text)60   void set_text(const std::string& text) {
61     text_ = text;
62     format_ |= static_cast<int>(AuraClipboardFormat::kText);
63   }
64 
markup_data() const65   const std::string& markup_data() const { return markup_data_; }
set_markup_data(const std::string & markup_data)66   void set_markup_data(const std::string& markup_data) {
67     markup_data_ = markup_data;
68     format_ |= static_cast<int>(AuraClipboardFormat::kHtml);
69   }
70 
rtf_data() const71   const std::string& rtf_data() const { return rtf_data_; }
SetRTFData(const std::string & rtf_data)72   void SetRTFData(const std::string& rtf_data) {
73     rtf_data_ = rtf_data;
74     format_ |= static_cast<int>(AuraClipboardFormat::kRtf);
75   }
76 
url() const77   const std::string& url() const { return url_; }
set_url(const std::string & url)78   void set_url(const std::string& url) {
79     url_ = url;
80     format_ |= static_cast<int>(AuraClipboardFormat::kHtml);
81   }
82 
bookmark_title() const83   const std::string& bookmark_title() const { return bookmark_title_; }
set_bookmark_title(const std::string & bookmark_title)84   void set_bookmark_title(const std::string& bookmark_title) {
85     bookmark_title_ = bookmark_title;
86     format_ |= static_cast<int>(AuraClipboardFormat::kBookmark);
87   }
88 
bookmark_url() const89   const std::string& bookmark_url() const { return bookmark_url_; }
set_bookmark_url(const std::string & bookmark_url)90   void set_bookmark_url(const std::string& bookmark_url) {
91     bookmark_url_ = bookmark_url;
92     format_ |= static_cast<int>(AuraClipboardFormat::kBookmark);
93   }
94 
bitmap() const95   const SkBitmap& bitmap() const { return bitmap_; }
SetBitmapData(const SkBitmap & bitmap)96   void SetBitmapData(const SkBitmap& bitmap) {
97     if (!skia::SkBitmapToN32OpaqueOrPremul(bitmap, &bitmap_)) {
98       NOTREACHED() << "Unable to convert bitmap for clipboard";
99       return;
100     }
101     format_ |= static_cast<int>(AuraClipboardFormat::kBitmap);
102   }
103 
custom_data_format() const104   const std::string& custom_data_format() const { return custom_data_format_; }
custom_data_data() const105   const std::string& custom_data_data() const { return custom_data_data_; }
SetCustomData(const std::string & data_format,const std::string & data_data)106   void SetCustomData(const std::string& data_format,
107                      const std::string& data_data) {
108     if (data_data.size() == 0) {
109       custom_data_data_.clear();
110       custom_data_format_.clear();
111       return;
112     }
113     custom_data_data_ = data_data;
114     custom_data_format_ = data_format;
115     format_ |= static_cast<int>(AuraClipboardFormat::kCustom);
116   }
117 
web_smart_paste() const118   bool web_smart_paste() const { return web_smart_paste_; }
set_web_smart_paste(bool web_smart_paste)119   void set_web_smart_paste(bool web_smart_paste) {
120     web_smart_paste_ = web_smart_paste;
121     format_ |= static_cast<int>(AuraClipboardFormat::kWeb);
122   }
123 
124  private:
125   // Plain text in UTF8 format.
126   std::string text_;
127 
128   // HTML markup data in UTF8 format.
129   std::string markup_data_;
130   std::string url_;
131 
132   // RTF data.
133   std::string rtf_data_;
134 
135   // Bookmark title in UTF8 format.
136   std::string bookmark_title_;
137   std::string bookmark_url_;
138 
139   // Filenames.
140   std::vector<std::string> files_;
141 
142   // Bitmap images.
143   SkBitmap bitmap_;
144 
145   // Data with custom format.
146   std::string custom_data_format_;
147   std::string custom_data_data_;
148 
149   // WebKit smart paste data.
150   bool web_smart_paste_;
151 
152   int format_;
153 
154   DISALLOW_COPY_AND_ASSIGN(ClipboardData);
155 };
156 
157 }  // namespace
158 
159 // Platform clipboard implementation for Aura. This handles things like format
160 // conversion, versioning of clipboard items etc. The goal is to roughly provide
161 // a substitute to platform clipboards on other platforms such as GtkClipboard
162 // on gtk or winapi clipboard on win.
163 class AuraClipboard {
164  public:
AuraClipboard()165   AuraClipboard() : sequence_number_(0) {
166   }
167 
168   ~AuraClipboard() = default;
169 
Clear()170   void Clear() {
171     sequence_number_++;
172     data_list_.clear();
173     ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
174   }
175 
sequence_number() const176   uint64_t sequence_number() const {
177     return sequence_number_;
178   }
179 
180   // Returns the data currently on the top of the clipboard stack, nullptr if
181   // the clipboard stack is empty.
GetData() const182   const ClipboardData* GetData() const {
183     if (data_list_.empty())
184       return nullptr;
185     return data_list_.front().get();
186   }
187 
188   // Returns true if the data on top of the clipboard stack has format |format|
189   // or another format that can be converted to |format|.
IsFormatAvailable(AuraClipboardFormat format) const190   bool IsFormatAvailable(AuraClipboardFormat format) const {
191     switch (format) {
192       case AuraClipboardFormat::kText:
193         return HasFormat(AuraClipboardFormat::kText) ||
194                HasFormat(AuraClipboardFormat::kBookmark);
195       default:
196         return HasFormat(format);
197     }
198   }
199 
200   // Reads text from the data at the top of clipboard stack.
ReadText(base::string16 * result) const201   void ReadText(base::string16* result) const {
202     std::string utf8_result;
203     ReadAsciiText(&utf8_result);
204     *result = base::UTF8ToUTF16(utf8_result);
205   }
206 
207   // Reads ASCII text from the data at the top of clipboard stack.
ReadAsciiText(std::string * result) const208   void ReadAsciiText(std::string* result) const {
209     result->clear();
210     const ClipboardData* data = GetData();
211     if (!data)
212       return;
213     if (HasFormat(AuraClipboardFormat::kText))
214       *result = data->text();
215     else if (HasFormat(AuraClipboardFormat::kHtml))
216       *result = data->markup_data();
217     else if (HasFormat(AuraClipboardFormat::kBookmark))
218       *result = data->bookmark_url();
219   }
220 
221   // Reads HTML from the data at the top of clipboard stack.
ReadHTML(base::string16 * markup,std::string * src_url,uint32_t * fragment_start,uint32_t * fragment_end) const222   void ReadHTML(base::string16* markup,
223                 std::string* src_url,
224                 uint32_t* fragment_start,
225                 uint32_t* fragment_end) const {
226     markup->clear();
227     if (src_url)
228       src_url->clear();
229     *fragment_start = 0;
230     *fragment_end = 0;
231 
232     if (!HasFormat(AuraClipboardFormat::kHtml))
233       return;
234 
235     const ClipboardData* data = GetData();
236     *markup = base::UTF8ToUTF16(data->markup_data());
237     *src_url = data->url();
238 
239     *fragment_start = 0;
240     DCHECK_LE(markup->length(), std::numeric_limits<uint32_t>::max());
241     *fragment_end = static_cast<uint32_t>(markup->length());
242   }
243 
244   // Reads RTF from the data at the top of clipboard stack.
ReadRTF(std::string * result) const245   void ReadRTF(std::string* result) const {
246     result->clear();
247     const ClipboardData* data = GetData();
248     if (!HasFormat(AuraClipboardFormat::kRtf))
249       return;
250 
251     *result = data->rtf_data();
252   }
253 
254   // Reads image from the data at the top of clipboard stack.
ReadImage() const255   SkBitmap ReadImage() const {
256     SkBitmap img;
257     if (!HasFormat(AuraClipboardFormat::kBitmap))
258       return img;
259 
260     // A shallow copy should be fine here, but just to be safe...
261     const SkBitmap& clipboard_bitmap = GetData()->bitmap();
262     if (img.tryAllocPixels(clipboard_bitmap.info())) {
263       clipboard_bitmap.readPixels(img.info(), img.getPixels(), img.rowBytes(),
264                                   0, 0);
265     }
266     return img;
267   }
268 
269   // Reads data of type |type| from the data at the top of clipboard stack.
ReadCustomData(const base::string16 & type,base::string16 * result) const270   void ReadCustomData(const base::string16& type,
271                       base::string16* result) const {
272     result->clear();
273     const ClipboardData* data = GetData();
274     if (!HasFormat(AuraClipboardFormat::kCustom))
275       return;
276 
277     ReadCustomDataForType(data->custom_data_data().c_str(),
278                           data->custom_data_data().size(), type, result);
279   }
280 
281   // Reads bookmark from the data at the top of clipboard stack.
ReadBookmark(base::string16 * title,std::string * url) const282   void ReadBookmark(base::string16* title, std::string* url) const {
283     if (title)
284       title->clear();
285     if (url)
286       url->clear();
287     if (!HasFormat(AuraClipboardFormat::kBookmark))
288       return;
289 
290     const ClipboardData* data = GetData();
291     if (title)
292       *title = base::UTF8ToUTF16(data->bookmark_title());
293     if (url)
294       *url = data->bookmark_url();
295   }
296 
ReadData(const std::string & type,std::string * result) const297   void ReadData(const std::string& type, std::string* result) const {
298     result->clear();
299     const ClipboardData* data = GetData();
300     if (!HasFormat(AuraClipboardFormat::kCustom) ||
301         type != data->custom_data_format())
302       return;
303 
304     *result = data->custom_data_data();
305   }
306 
307   // Writes |data| to the top of the clipboard stack.
WriteData(std::unique_ptr<ClipboardData> data)308   void WriteData(std::unique_ptr<ClipboardData> data) {
309     DCHECK(data);
310     AddToListEnsuringSize(std::move(data));
311     ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
312   }
313 
314  private:
315   // True if the data on top of the clipboard stack has format |format|.
HasFormat(AuraClipboardFormat format) const316   bool HasFormat(AuraClipboardFormat format) const {
317     const ClipboardData* data = GetData();
318     return data ? data->format() & static_cast<int>(format) : false;
319   }
320 
AddToListEnsuringSize(std::unique_ptr<ClipboardData> data)321   void AddToListEnsuringSize(std::unique_ptr<ClipboardData> data) {
322     DCHECK(data);
323     sequence_number_++;
324     data_list_.push_front(std::move(data));
325 
326     // If the size of list becomes more than the maximum allowed, we delete the
327     // last element.
328     if (data_list_.size() > kMaxClipboardSize) {
329       data_list_.pop_back();
330     }
331   }
332 
333   // Stack containing various versions of ClipboardData.
334   std::list<std::unique_ptr<ClipboardData>> data_list_;
335 
336   // Sequence number uniquely identifying clipboard state.
337   uint64_t sequence_number_;
338 
339   DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
340 };
341 
342 // Helper class to build a ClipboardData object and write it to clipboard.
343 class ClipboardDataBuilder {
344  public:
CommitToClipboard(AuraClipboard * clipboard)345   static void CommitToClipboard(AuraClipboard* clipboard) {
346     clipboard->WriteData(TakeCurrentData());
347   }
348 
WriteText(const char * text_data,size_t text_len)349   static void WriteText(const char* text_data, size_t text_len) {
350     ClipboardData* data = GetCurrentData();
351     data->set_text(std::string(text_data, text_len));
352   }
353 
WriteHTML(const char * markup_data,size_t markup_len,const char * url_data,size_t url_len)354   static void WriteHTML(const char* markup_data,
355                         size_t markup_len,
356                         const char* url_data,
357                         size_t url_len) {
358     ClipboardData* data = GetCurrentData();
359     data->set_markup_data(std::string(markup_data, markup_len));
360     data->set_url(std::string(url_data, url_len));
361   }
362 
WriteRTF(const char * rtf_data,size_t rtf_len)363   static void WriteRTF(const char* rtf_data, size_t rtf_len) {
364     ClipboardData* data = GetCurrentData();
365     data->SetRTFData(std::string(rtf_data, rtf_len));
366   }
367 
WriteBookmark(const char * title_data,size_t title_len,const char * url_data,size_t url_len)368   static void WriteBookmark(const char* title_data,
369                             size_t title_len,
370                             const char* url_data,
371                             size_t url_len) {
372     ClipboardData* data = GetCurrentData();
373     data->set_bookmark_title(std::string(title_data, title_len));
374     data->set_bookmark_url(std::string(url_data, url_len));
375   }
376 
WriteWebSmartPaste()377   static void WriteWebSmartPaste() {
378     ClipboardData* data = GetCurrentData();
379     data->set_web_smart_paste(true);
380   }
381 
WriteBitmap(const SkBitmap & bitmap)382   static void WriteBitmap(const SkBitmap& bitmap) {
383     ClipboardData* data = GetCurrentData();
384     data->SetBitmapData(bitmap);
385   }
386 
WriteData(const std::string & format,const char * data_data,size_t data_len)387   static void WriteData(const std::string& format,
388                         const char* data_data,
389                         size_t data_len) {
390     ClipboardData* data = GetCurrentData();
391     data->SetCustomData(format, std::string(data_data, data_len));
392   }
393 
394  private:
GetCurrentData()395   static ClipboardData* GetCurrentData() {
396     if (!current_data_)
397       current_data_ = new ClipboardData;
398     return current_data_;
399   }
400 
TakeCurrentData()401   static std::unique_ptr<ClipboardData> TakeCurrentData() {
402     std::unique_ptr<ClipboardData> data = base::WrapUnique(GetCurrentData());
403     current_data_ = nullptr;
404     return data;
405   }
406   // This is a raw pointer instead of a std::unique_ptr to avoid adding a
407   // static initializer.
408   static ClipboardData* current_data_;
409 };
410 
411 ClipboardData* ClipboardDataBuilder::current_data_ = nullptr;
412 
413 // linux-chromeos uses aura clipboard by default, but supports ozone x11
414 // with flag --use-system-clipbboard.
415 #if !defined(OS_CHROMEOS) || !BUILDFLAG(OZONE_PLATFORM_X11)
416 // Clipboard factory method.
Create()417 Clipboard* Clipboard::Create() {
418   return new ClipboardAura;
419 }
420 #endif
421 
422 // ClipboardAura implementation.
ClipboardAura()423 ClipboardAura::ClipboardAura()
424     : clipboard_internal_(std::make_unique<AuraClipboard>()) {
425   DCHECK(CalledOnValidThread());
426 }
427 
~ClipboardAura()428 ClipboardAura::~ClipboardAura() {
429   DCHECK(CalledOnValidThread());
430 }
431 
OnPreShutdown()432 void ClipboardAura::OnPreShutdown() {}
433 
GetSequenceNumber(ClipboardBuffer buffer) const434 uint64_t ClipboardAura::GetSequenceNumber(ClipboardBuffer buffer) const {
435   DCHECK(CalledOnValidThread());
436   return clipboard_internal_->sequence_number();
437 }
438 
IsFormatAvailable(const ClipboardFormatType & format,ClipboardBuffer buffer) const439 bool ClipboardAura::IsFormatAvailable(const ClipboardFormatType& format,
440                                       ClipboardBuffer buffer) const {
441   DCHECK(CalledOnValidThread());
442   DCHECK(IsSupportedClipboardBuffer(buffer));
443   if (ClipboardFormatType::GetPlainTextType().Equals(format) ||
444       ClipboardFormatType::GetUrlType().Equals(format))
445     return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kText);
446   if (ClipboardFormatType::GetHtmlType().Equals(format))
447     return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kHtml);
448   if (ClipboardFormatType::GetRtfType().Equals(format))
449     return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kRtf);
450   if (ClipboardFormatType::GetBitmapType().Equals(format))
451     return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kBitmap);
452   if (ClipboardFormatType::GetWebKitSmartPasteType().Equals(format))
453     return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kWeb);
454   const ClipboardData* data = clipboard_internal_->GetData();
455   return data && data->custom_data_format() == format.GetName();
456 }
457 
Clear(ClipboardBuffer buffer)458 void ClipboardAura::Clear(ClipboardBuffer buffer) {
459   DCHECK(CalledOnValidThread());
460   DCHECK(IsSupportedClipboardBuffer(buffer));
461   clipboard_internal_->Clear();
462 }
463 
ReadAvailableTypes(ClipboardBuffer buffer,std::vector<base::string16> * types,bool * contains_filenames) const464 void ClipboardAura::ReadAvailableTypes(ClipboardBuffer buffer,
465                                        std::vector<base::string16>* types,
466                                        bool* contains_filenames) const {
467   DCHECK(CalledOnValidThread());
468   if (!types || !contains_filenames) {
469     NOTREACHED();
470     return;
471   }
472 
473   types->clear();
474   *contains_filenames = false;
475   if (IsFormatAvailable(ClipboardFormatType::GetPlainTextType(), buffer))
476     types->push_back(
477         base::UTF8ToUTF16(ClipboardFormatType::GetPlainTextType().GetName()));
478   if (IsFormatAvailable(ClipboardFormatType::GetHtmlType(), buffer))
479     types->push_back(
480         base::UTF8ToUTF16(ClipboardFormatType::GetHtmlType().GetName()));
481   if (IsFormatAvailable(ClipboardFormatType::GetRtfType(), buffer))
482     types->push_back(
483         base::UTF8ToUTF16(ClipboardFormatType::GetRtfType().GetName()));
484   if (IsFormatAvailable(ClipboardFormatType::GetBitmapType(), buffer))
485     types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
486 
487   if (clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kCustom) &&
488       clipboard_internal_->GetData()) {
489     ReadCustomDataTypes(
490         clipboard_internal_->GetData()->custom_data_data().c_str(),
491         clipboard_internal_->GetData()->custom_data_data().size(), types);
492   }
493 }
494 
495 std::vector<base::string16>
ReadAvailablePlatformSpecificFormatNames(ClipboardBuffer buffer) const496 ClipboardAura::ReadAvailablePlatformSpecificFormatNames(
497     ClipboardBuffer buffer) const {
498   DCHECK(CalledOnValidThread());
499 
500   std::vector<base::string16> types;
501 
502   // Includes all non-pickled AvailableTypes.
503   if (IsFormatAvailable(ClipboardFormatType::GetPlainTextType(), buffer)) {
504     types.push_back(
505         base::UTF8ToUTF16(ClipboardFormatType::GetPlainTextType().GetName()));
506   }
507   if (IsFormatAvailable(ClipboardFormatType::GetHtmlType(), buffer)) {
508     types.push_back(
509         base::UTF8ToUTF16(ClipboardFormatType::GetHtmlType().GetName()));
510   }
511   if (IsFormatAvailable(ClipboardFormatType::GetRtfType(), buffer)) {
512     types.push_back(
513         base::UTF8ToUTF16(ClipboardFormatType::GetRtfType().GetName()));
514   }
515   if (IsFormatAvailable(ClipboardFormatType::GetBitmapType(), buffer)) {
516     types.push_back(base::UTF8ToUTF16(kMimeTypePNG));
517   }
518 
519   return types;
520 }
521 
ReadText(ClipboardBuffer buffer,base::string16 * result) const522 void ClipboardAura::ReadText(ClipboardBuffer buffer,
523                              base::string16* result) const {
524   DCHECK(CalledOnValidThread());
525   clipboard_internal_->ReadText(result);
526 }
527 
ReadAsciiText(ClipboardBuffer buffer,std::string * result) const528 void ClipboardAura::ReadAsciiText(ClipboardBuffer buffer,
529                                   std::string* result) const {
530   DCHECK(CalledOnValidThread());
531   clipboard_internal_->ReadAsciiText(result);
532 }
533 
ReadHTML(ClipboardBuffer buffer,base::string16 * markup,std::string * src_url,uint32_t * fragment_start,uint32_t * fragment_end) const534 void ClipboardAura::ReadHTML(ClipboardBuffer buffer,
535                              base::string16* markup,
536                              std::string* src_url,
537                              uint32_t* fragment_start,
538                              uint32_t* fragment_end) const {
539   DCHECK(CalledOnValidThread());
540   clipboard_internal_->ReadHTML(markup, src_url, fragment_start, fragment_end);
541 }
542 
ReadRTF(ClipboardBuffer buffer,std::string * result) const543 void ClipboardAura::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
544   DCHECK(CalledOnValidThread());
545   clipboard_internal_->ReadRTF(result);
546 }
547 
ReadImage(ClipboardBuffer buffer,ReadImageCallback callback) const548 void ClipboardAura::ReadImage(ClipboardBuffer buffer,
549                               ReadImageCallback callback) const {
550   DCHECK(CalledOnValidThread());
551   std::move(callback).Run(clipboard_internal_->ReadImage());
552 }
553 
ReadCustomData(ClipboardBuffer buffer,const base::string16 & type,base::string16 * result) const554 void ClipboardAura::ReadCustomData(ClipboardBuffer buffer,
555                                    const base::string16& type,
556                                    base::string16* result) const {
557   DCHECK(CalledOnValidThread());
558   clipboard_internal_->ReadCustomData(type, result);
559 }
560 
ReadBookmark(base::string16 * title,std::string * url) const561 void ClipboardAura::ReadBookmark(base::string16* title,
562                                  std::string* url) const {
563   DCHECK(CalledOnValidThread());
564   clipboard_internal_->ReadBookmark(title, url);
565 }
566 
ReadData(const ClipboardFormatType & format,std::string * result) const567 void ClipboardAura::ReadData(const ClipboardFormatType& format,
568                              std::string* result) const {
569   DCHECK(CalledOnValidThread());
570   clipboard_internal_->ReadData(format.GetName(), result);
571 }
572 
WritePortableRepresentations(ClipboardBuffer buffer,const ObjectMap & objects)573 void ClipboardAura::WritePortableRepresentations(ClipboardBuffer buffer,
574                                                  const ObjectMap& objects) {
575   DCHECK(CalledOnValidThread());
576   DCHECK(IsSupportedClipboardBuffer(buffer));
577   for (const auto& object : objects)
578     DispatchPortableRepresentation(object.first, object.second);
579   ClipboardDataBuilder::CommitToClipboard(clipboard_internal_.get());
580 }
581 
WritePlatformRepresentations(ClipboardBuffer buffer,std::vector<Clipboard::PlatformRepresentation> platform_representations)582 void ClipboardAura::WritePlatformRepresentations(
583     ClipboardBuffer buffer,
584     std::vector<Clipboard::PlatformRepresentation> platform_representations) {
585   DCHECK(CalledOnValidThread());
586   DCHECK(IsSupportedClipboardBuffer(buffer));
587 
588   DispatchPlatformRepresentations(std::move(platform_representations));
589 
590   ClipboardDataBuilder::CommitToClipboard(clipboard_internal_.get());
591 }
592 
WriteText(const char * text_data,size_t text_len)593 void ClipboardAura::WriteText(const char* text_data, size_t text_len) {
594   ClipboardDataBuilder::WriteText(text_data, text_len);
595 }
596 
WriteHTML(const char * markup_data,size_t markup_len,const char * url_data,size_t url_len)597 void ClipboardAura::WriteHTML(const char* markup_data,
598                               size_t markup_len,
599                               const char* url_data,
600                               size_t url_len) {
601   ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len);
602 }
603 
WriteRTF(const char * rtf_data,size_t data_len)604 void ClipboardAura::WriteRTF(const char* rtf_data, size_t data_len) {
605   ClipboardDataBuilder::WriteRTF(rtf_data, data_len);
606 }
607 
WriteBookmark(const char * title_data,size_t title_len,const char * url_data,size_t url_len)608 void ClipboardAura::WriteBookmark(const char* title_data,
609                                   size_t title_len,
610                                   const char* url_data,
611                                   size_t url_len) {
612   ClipboardDataBuilder::WriteBookmark(title_data, title_len, url_data, url_len);
613 }
614 
WriteWebSmartPaste()615 void ClipboardAura::WriteWebSmartPaste() {
616   ClipboardDataBuilder::WriteWebSmartPaste();
617 }
618 
WriteBitmap(const SkBitmap & bitmap)619 void ClipboardAura::WriteBitmap(const SkBitmap& bitmap) {
620   ClipboardDataBuilder::WriteBitmap(bitmap);
621 }
622 
WriteData(const ClipboardFormatType & format,const char * data_data,size_t data_len)623 void ClipboardAura::WriteData(const ClipboardFormatType& format,
624                               const char* data_data,
625                               size_t data_len) {
626   ClipboardDataBuilder::WriteData(format.GetName(), data_data, data_len);
627 }
628 
629 }  // namespace ui
630