diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 16:35:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 15:45:54 +0000 |
commit | 32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch) | |
tree | eeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/ui/base/clipboard | |
parent | 99677208ff3b216fdfec551fbe548da5520cd6fb (diff) | |
download | qtwebengine-chromium-32f5a1c56531e4210bc4cf8d8c7825d66e081888.tar.gz |
BASELINE: Update Chromium to 87.0.4280.67
Change-Id: Ib157360be8c2ffb2c73125751a89f60e049c1d54
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/ui/base/clipboard')
39 files changed, 571 insertions, 221 deletions
diff --git a/chromium/ui/base/clipboard/BUILD.gn b/chromium/ui/base/clipboard/BUILD.gn index 32a6ff50524..36048a6bc82 100644 --- a/chromium/ui/base/clipboard/BUILD.gn +++ b/chromium/ui/base/clipboard/BUILD.gn @@ -6,12 +6,6 @@ import("///ui/ozone/ozone.gni") import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") -# Reset sources_assignment_filter for the BUILD.gn file to prevent -# regression during the migration of Chromium away from the feature. -# See docs/no_sources_assignment_filter.md for more information. -# TODO(crbug.com/1018739): remove this when migration is done. -set_sources_assignment_filter([]) - component("clipboard_types") { output_name = "ui_base_clipboard_types" sources = [ @@ -67,11 +61,13 @@ component("clipboard") { "clipboard.h", "clipboard_data_endpoint.cc", "clipboard_data_endpoint.h", + "clipboard_dlp_controller.cc", "clipboard_dlp_controller.h", "clipboard_metrics.cc", "clipboard_metrics.h", "clipboard_monitor.cc", "clipboard_monitor.h", + "clipboard_observer.cc", "clipboard_observer.h", "custom_data_helper.cc", "custom_data_helper.h", @@ -231,7 +227,8 @@ source_set("clipboard_test") { ] } - if (use_aura && !chromeos_is_browser_only && !use_x11 && !is_win) { + if (use_aura && !chromeos_is_browser_only && !use_x11 && !is_win && + !use_ozone) { sources += [ "clipboard_data_unittest.cc", "clipboard_non_backed_unittest.cc", @@ -245,6 +242,7 @@ source_set("clipboard_test") { "//testing/gtest", "//ui/events/platform", "//ui/gfx:test_support", + "//url:url", ] if (is_mac) { diff --git a/chromium/ui/base/clipboard/clipboard.cc b/chromium/ui/base/clipboard/clipboard.cc index a7722e261c1..b7445c0a98b 100644 --- a/chromium/ui/base/clipboard/clipboard.cc +++ b/chromium/ui/base/clipboard/clipboard.cc @@ -127,6 +127,10 @@ void Clipboard::DispatchPortableRepresentation(PortableFormat format, } break; + case PortableFormat::kSvg: + WriteSvg(&(params[0].front()), params[0].size()); + break; + case PortableFormat::kRtf: WriteRTF(&(params[0].front()), params[0].size()); break; diff --git a/chromium/ui/base/clipboard/clipboard.h b/chromium/ui/base/clipboard/clipboard.h index 62004e65921..e596a20b40e 100644 --- a/chromium/ui/base/clipboard/clipboard.h +++ b/chromium/ui/base/clipboard/clipboard.h @@ -27,7 +27,6 @@ #include "build/build_config.h" #include "mojo/public/cpp/base/big_buffer.h" #include "ui/base/clipboard/clipboard_buffer.h" -#include "ui/base/clipboard/clipboard_dlp_controller.h" #include "ui/base/clipboard/clipboard_format_type.h" class SkBitmap; @@ -108,11 +107,6 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard // whether it has changed. virtual uint64_t GetSequenceNumber(ClipboardBuffer buffer) const = 0; - // Sets the data leak prevention controller for the clipboard. This function - // will be used only on Chrome OS. - virtual void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) = 0; - // Tests whether the clipboard contains a certain format. // TODO(crbug.com/1103614): Update |data_dst| in all references to its // appropriate ClipboardDataEndpoint for web-originates uses. @@ -180,6 +174,12 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard uint32_t* fragment_start, uint32_t* fragment_end) const = 0; + // Reads an SVG image from the clipboard, if available. + // TODO(crbug.com/1103614): Update |data_dst| in all references to its + // appropriate ClipboardDataEndpoint for web-originates uses. + virtual void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const = 0; // Reads RTF from the clipboard, if available. Stores the result as a byte // vector. // TODO(crbug.com/1103614): Update |data_dst| in all references to its @@ -255,6 +255,7 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard kText, kWebkit, kData, // Arbitrary block of bytes. + kSvg, }; // TODO (https://crbug.com/994928): Rename ObjectMap-related types. @@ -331,6 +332,8 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard const char* url_data, size_t url_len) = 0; + virtual void WriteSvg(const char* markup_data, size_t markup_len) = 0; + virtual void WriteRTF(const char* rtf_data, size_t data_len) = 0; virtual void WriteBookmark(const char* title_data, diff --git a/chromium/ui/base/clipboard/clipboard_android.cc b/chromium/ui/base/clipboard/clipboard_android.cc index f8bcfc65d7c..caf32eb42ab 100644 --- a/chromium/ui/base/clipboard/clipboard_android.cc +++ b/chromium/ui/base/clipboard/clipboard_android.cc @@ -27,21 +27,27 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/clipboard_data_endpoint.h" +#include "ui/base/clipboard/clipboard_format_type.h" #include "ui/base/clipboard/clipboard_metrics.h" #include "ui/base/ui_base_jni_headers/Clipboard_jni.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/image/image.h" -// TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, +// TODO:(andrewhayden) Support additional formats in Android: URI, HTML, // HTML+text now that Android's clipboard system supports them, then nuke the // legacy implementation note below. // Legacy implementation note: -// The Android clipboard system used to only support text format. So we used the -// Android system when some text was added or retrieved from the system. For -// anything else, we STILL store the value in some process wide static -// variable protected by a lock. So the (non-text) clipboard will only work -// within the same process. +// The Android clipboard, and hence `ClipboardAndroid` as well, used to only +// support text. Since then, bitmap support has been added, but not support +// for any other formats. +// +// Therefore, Clipboard data is stored: +// - on the Android system, for text and bitmaps. +// - in a process-wide static variable protected by a lock, for other formats. +// +// These "other formats" only work within the same process, and can't be copied +// between Android applications. using base::android::AttachCurrentThread; using base::android::ClearException; @@ -83,16 +89,16 @@ class ClipboardMap { ClipboardMap(); void SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb); void SetJavaSideNativePtr(Clipboard* clipboard); - std::string Get(const std::string& format); + std::string Get(const ClipboardFormatType& format); void GetImage(ReadImageCallback callback); uint64_t GetSequenceNumber() const; base::Time GetLastModifiedTime() const; void ClearLastModifiedTime(); - bool HasFormat(const std::string& format); - std::vector<std::string> GetFormats(); + bool HasFormat(const ClipboardFormatType& format); + std::vector<ClipboardFormatType> GetFormats(); void OnPrimaryClipboardChanged(); void OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms); - void Set(const std::string& format, const std::string& data); + void Set(const ClipboardFormatType& format, const std::string& data); void CommitToAndroidClipboard(); void Clear(); @@ -112,8 +118,7 @@ class ClipboardMap { // Updates |map_| and |map_state_| if necessary by fetching data from Java. void UpdateFromAndroidClipboard(); - // TODO(huangdarwin): Refactor this to hold base::string16. - std::map<std::string, std::string> map_ GUARDED_BY(lock_); + std::map<ClipboardFormatType, std::string> map_ GUARDED_BY(lock_); MapState map_state_; // This lock is for read/write |map_|. @@ -144,10 +149,10 @@ void ClipboardMap::SetJavaSideNativePtr(Clipboard* clipboard) { reinterpret_cast<intptr_t>(clipboard)); } -std::string ClipboardMap::Get(const std::string& format) { +std::string ClipboardMap::Get(const ClipboardFormatType& format) { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); - std::map<std::string, std::string>::const_iterator it = map_.find(format); + auto it = map_.find(format); return it == map_.end() ? std::string() : it->second; } @@ -169,16 +174,16 @@ void ClipboardMap::ClearLastModifiedTime() { UpdateLastModifiedTime(base::Time()); } -bool ClipboardMap::HasFormat(const std::string& format) { +bool ClipboardMap::HasFormat(const ClipboardFormatType& format) { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); return base::Contains(map_, format); } -std::vector<std::string> ClipboardMap::GetFormats() { +std::vector<ClipboardFormatType> ClipboardMap::GetFormats() { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); - std::vector<std::string> formats; + std::vector<ClipboardFormatType> formats; formats.reserve(map_.size()); for (const auto& it : map_) formats.push_back(it.first); @@ -200,7 +205,8 @@ void ClipboardMap::OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms) { } } -void ClipboardMap::Set(const std::string& format, const std::string& data) { +void ClipboardMap::Set(const ClipboardFormatType& format, + const std::string& data) { base::AutoLock lock(lock_); map_[format] = data; map_state_ = MapState::kPreparingCommit; @@ -209,30 +215,27 @@ void ClipboardMap::Set(const std::string& format, const std::string& data) { void ClipboardMap::CommitToAndroidClipboard() { JNIEnv* env = AttachCurrentThread(); base::AutoLock lock(lock_); - if (base::Contains(map_, ClipboardFormatType::GetHtmlType().GetName())) { + if (base::Contains(map_, ClipboardFormatType::GetHtmlType())) { // Android's API for storing HTML content on the clipboard requires a plain- // text representation to be available as well. - if (!base::Contains(map_, - ClipboardFormatType::GetPlainTextType().GetName())) + if (!base::Contains(map_, ClipboardFormatType::GetPlainTextType())) return; - ScopedJavaLocalRef<jstring> html = ConvertUTF8ToJavaString( - env, map_[ClipboardFormatType::GetHtmlType().GetName()]); + ScopedJavaLocalRef<jstring> html = + ConvertUTF8ToJavaString(env, map_[ClipboardFormatType::GetHtmlType()]); ScopedJavaLocalRef<jstring> text = ConvertUTF8ToJavaString( - env, map_[ClipboardFormatType::GetPlainTextType().GetName()]); + env, map_[ClipboardFormatType::GetPlainTextType()]); DCHECK(html.obj() && text.obj()); Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text); - } else if (base::Contains( - map_, ClipboardFormatType::GetPlainTextType().GetName())) { + } else if (base::Contains(map_, ClipboardFormatType::GetPlainTextType())) { ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString( - env, map_[ClipboardFormatType::GetPlainTextType().GetName()]); + env, map_[ClipboardFormatType::GetPlainTextType()]); DCHECK(str.obj()); Java_Clipboard_setText(env, clipboard_manager_, str); - } else if (base::Contains(map_, - ClipboardFormatType::GetBitmapType().GetName())) { - ScopedJavaLocalRef<jbyteArray> image_data = ToJavaByteArray( - env, map_[ClipboardFormatType::GetBitmapType().GetName()]); + } else if (base::Contains(map_, ClipboardFormatType::GetBitmapType())) { + ScopedJavaLocalRef<jbyteArray> image_data = + ToJavaByteArray(env, map_[ClipboardFormatType::GetBitmapType()]); ScopedJavaLocalRef<jstring> image_extension = ConvertUTF8ToJavaString(env, kPngExtension); DCHECK(image_data.obj()); @@ -262,21 +265,22 @@ void ClipboardMap::SetLastModifiedTimeWithoutRunningCallback(base::Time time) { last_modified_time_ = time; } -// Add a key:jstr pair to map, if jstr is null or is empty, then remove that +// Add a format:jstr pair to map, if jstr is null or is empty, then remove that // entry. void JNI_Clipboard_AddMapEntry(JNIEnv* env, - std::map<std::string, std::string>* map, - const char* key, + std::map<ClipboardFormatType, std::string>* map, + const ClipboardFormatType& format, const ScopedJavaLocalRef<jstring>& jstr) { if (jstr.is_null()) { - map->erase(key); + map->erase(format); return; } + std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); if (!str.empty()) { - (*map)[key] = str; + (*map)[format] = str; } else { - map->erase(key); + map->erase(format); } } @@ -303,12 +307,12 @@ void ClipboardMap::UpdateFromAndroidClipboard() { ScopedJavaLocalRef<jstring> jimageuri = Java_Clipboard_getImageUriString(env, clipboard_manager_); + JNI_Clipboard_AddMapEntry(env, &map_, ClipboardFormatType::GetPlainTextType(), + jtext); + JNI_Clipboard_AddMapEntry(env, &map_, ClipboardFormatType::GetHtmlType(), + jhtml); JNI_Clipboard_AddMapEntry( - env, &map_, ClipboardFormatType::GetPlainTextType().GetName().c_str(), - jtext); - JNI_Clipboard_AddMapEntry( - env, &map_, ClipboardFormatType::GetHtmlType().GetName().c_str(), jhtml); - JNI_Clipboard_AddMapEntry(env, &map_, kMimeTypeImageURI, jimageuri); + env, &map_, ClipboardFormatType::GetType(kMimeTypeImageURI), jimageuri); map_state_ = MapState::kUpToDate; } @@ -366,11 +370,6 @@ uint64_t ClipboardAndroid::GetSequenceNumber( return g_map.Get().GetSequenceNumber(); } -void ClipboardAndroid::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - NOTIMPLEMENTED(); -} - // |data_dst| is not used. It's only passed to be consistent with other // platforms. bool ClipboardAndroid::IsFormatAvailable( @@ -381,9 +380,10 @@ bool ClipboardAndroid::IsFormatAvailable( DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); if (format == ClipboardFormatType::GetBitmapType()) { - return g_map.Get().HasFormat(kMimeTypeImageURI); + return g_map.Get().HasFormat( + ClipboardFormatType::GetType(kMimeTypeImageURI)); } - return g_map.Get().HasFormat(format.GetName()); + return g_map.Get().HasFormat(format); } void ClipboardAndroid::Clear(ClipboardBuffer buffer) { @@ -427,12 +427,12 @@ ClipboardAndroid::ReadAvailablePlatformSpecificFormatNames( ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const { DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); - std::vector<std::string> formats = g_map.Get().GetFormats(); + std::vector<ClipboardFormatType> formats = g_map.Get().GetFormats(); std::vector<base::string16> types; types.reserve(formats.size()); - for (const std::string& format : formats) - types.push_back(base::UTF8ToUTF16(format)); + for (const ClipboardFormatType& format : formats) + types.push_back(base::UTF8ToUTF16(format.GetName())); return types; } @@ -457,7 +457,7 @@ void ClipboardAndroid::ReadAsciiText(ClipboardBuffer buffer, DCHECK(CalledOnValidThread()); DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); RecordRead(ClipboardFormatMetric::kText); - *result = g_map.Get().Get(ClipboardFormatType::GetPlainTextType().GetName()); + *result = g_map.Get().Get(ClipboardFormatType::GetPlainTextType()); } // Note: |src_url| isn't really used. It is only implemented in Windows. @@ -475,8 +475,7 @@ void ClipboardAndroid::ReadHTML(ClipboardBuffer buffer, if (src_url) src_url->clear(); - std::string input = - g_map.Get().Get(ClipboardFormatType::GetHtmlType().GetName()); + std::string input = g_map.Get().Get(ClipboardFormatType::GetHtmlType()); *markup = base::UTF8ToUTF16(input); *fragment_start = 0; @@ -485,6 +484,17 @@ void ClipboardAndroid::ReadHTML(ClipboardBuffer buffer, // |data_dst| is not used. It's only passed to be consistent with other // platforms. +void ClipboardAndroid::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); + std::string utf8 = g_map.Get().Get(ClipboardFormatType::GetSvgType()); + *result = base::UTF8ToUTF16(utf8); +} + +// |data_dst| is not used. It's only passed to be consistent with other +// platforms. void ClipboardAndroid::ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const { @@ -529,7 +539,7 @@ void ClipboardAndroid::ReadData(const ClipboardFormatType& format, std::string* result) const { DCHECK(CalledOnValidThread()); RecordRead(ClipboardFormatMetric::kData); - *result = g_map.Get().Get(format.GetName()); + *result = g_map.Get().Get(format); } base::Time ClipboardAndroid::GetLastModifiedTime() const { @@ -575,7 +585,7 @@ void ClipboardAndroid::WritePlatformRepresentations( } void ClipboardAndroid::WriteText(const char* text_data, size_t text_len) { - g_map.Get().Set(ClipboardFormatType::GetPlainTextType().GetName(), + g_map.Get().Set(ClipboardFormatType::GetPlainTextType(), std::string(text_data, text_len)); } @@ -583,7 +593,12 @@ void ClipboardAndroid::WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len) { - g_map.Get().Set(ClipboardFormatType::GetHtmlType().GetName(), + g_map.Get().Set(ClipboardFormatType::GetHtmlType(), + std::string(markup_data, markup_len)); +} + +void ClipboardAndroid::WriteSvg(const char* markup_data, size_t markup_len) { + g_map.Get().Set(ClipboardFormatType::GetSvgType(), std::string(markup_data, markup_len)); } @@ -597,14 +612,14 @@ void ClipboardAndroid::WriteBookmark(const char* title_data, size_t title_len, const char* url_data, size_t url_len) { - g_map.Get().Set(ClipboardFormatType::GetUrlType().GetName(), + g_map.Get().Set(ClipboardFormatType::GetUrlType(), std::string(url_data, url_len)); } // Write an extra flavor that signifies WebKit was the last to modify the // pasteboard. This flavor has no data. void ClipboardAndroid::WriteWebSmartPaste() { - g_map.Get().Set(ClipboardFormatType::GetWebKitSmartPasteType().GetName(), + g_map.Get().Set(ClipboardFormatType::GetWebKitSmartPasteType(), std::string()); } @@ -615,13 +630,13 @@ void ClipboardAndroid::WriteBitmap(const SkBitmap& sk_bitmap) { gfx::Image::CreateFrom1xBitmap(sk_bitmap).As1xPNGBytes(); std::string packed(image_memory->front_as<char>(), image_memory->size()); - g_map.Get().Set(ClipboardFormatType::GetBitmapType().GetName(), packed); + g_map.Get().Set(ClipboardFormatType::GetBitmapType(), packed); } void ClipboardAndroid::WriteData(const ClipboardFormatType& format, const char* data_data, size_t data_len) { - g_map.Get().Set(format.GetName(), std::string(data_data, data_len)); + g_map.Get().Set(format, std::string(data_data, data_len)); } } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_android.h b/chromium/ui/base/clipboard/clipboard_android.h index 09258ce4de7..68ac63dd120 100644 --- a/chromium/ui/base/clipboard/clipboard_android.h +++ b/chromium/ui/base/clipboard/clipboard_android.h @@ -59,8 +59,6 @@ class ClipboardAndroid : public Clipboard { // Clipboard overrides: void OnPreShutdown() override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const override; @@ -83,6 +81,9 @@ class ClipboardAndroid : public Clipboard { std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -115,6 +116,7 @@ class ClipboardAndroid : public Clipboard { size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/clipboard_constants.cc b/chromium/ui/base/clipboard/clipboard_constants.cc index dc9197cc789..9fafdfaeea8 100644 --- a/chromium/ui/base/clipboard/clipboard_constants.cc +++ b/chromium/ui/base/clipboard/clipboard_constants.cc @@ -12,6 +12,7 @@ const char kMimeTypeURIList[] = "text/uri-list"; const char kMimeTypeMozillaURL[] = "text/x-moz-url"; const char kMimeTypeDownloadURL[] = "downloadurl"; const char kMimeTypeHTML[] = "text/html"; +const char kMimeTypeSvg[] = "image/svg+xml"; const char kMimeTypeRTF[] = "text/rtf"; const char kMimeTypePNG[] = "image/png"; diff --git a/chromium/ui/base/clipboard/clipboard_constants.h b/chromium/ui/base/clipboard/clipboard_constants.h index 8808a9917fd..aceeb8ea6e3 100644 --- a/chromium/ui/base/clipboard/clipboard_constants.h +++ b/chromium/ui/base/clipboard/clipboard_constants.h @@ -32,6 +32,7 @@ extern const char kMimeTypeDownloadURL[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeMozillaURL[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeHTML[]; +COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeSvg[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeRTF[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypePNG[]; @@ -56,6 +57,10 @@ extern const char kMimeTypePepperCustomData[]; #else // MacOS-specific Uniform Type Identifiers. +// SVG images. +COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) +extern NSString* const kImageSvg; + // Pickled data. COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern NSString* const kWebCustomDataPboardType; diff --git a/chromium/ui/base/clipboard/clipboard_constants_mac.mm b/chromium/ui/base/clipboard/clipboard_constants_mac.mm index 8633a201234..a7bc458f284 100644 --- a/chromium/ui/base/clipboard/clipboard_constants_mac.mm +++ b/chromium/ui/base/clipboard/clipboard_constants_mac.mm @@ -8,6 +8,7 @@ namespace ui { +NSString* const kImageSvg = @"public.svg-image"; // TODO(dcheng): This name is temporary. See crbug.com/106449. NSString* const kWebCustomDataPboardType = @"org.chromium.web-custom-data"; NSString* const kWebSmartPastePboardType = @"NeXT smart paste pasteboard type"; diff --git a/chromium/ui/base/clipboard/clipboard_data.cc b/chromium/ui/base/clipboard/clipboard_data.cc index d887c1ed725..9c83e264b11 100644 --- a/chromium/ui/base/clipboard/clipboard_data.cc +++ b/chromium/ui/base/clipboard/clipboard_data.cc @@ -28,6 +28,7 @@ ClipboardData::ClipboardData(const ClipboardData& other) { custom_data_format_ = other.custom_data_format_; custom_data_data_ = other.custom_data_data_; web_smart_paste_ = other.web_smart_paste_; + svg_data_ = other.svg_data_; src_ = other.src_ ? std::make_unique<ClipboardDataEndpoint>(*other.src_.get()) : nullptr; } @@ -45,6 +46,7 @@ bool ClipboardData::operator==(const ClipboardData& that) const { custom_data_format_ == that.custom_data_format() && custom_data_data_ == that.custom_data_data() && web_smart_paste_ == that.web_smart_paste() && + svg_data_ == that.svg_data() && gfx::BitmapsAreEqual(bitmap_, that.bitmap()) && (src_.get() ? (that.source() && *src_.get() == *that.source()) : !that.source()); diff --git a/chromium/ui/base/clipboard/clipboard_data.h b/chromium/ui/base/clipboard/clipboard_data.h index edbd558f6d6..a9eec23d950 100644 --- a/chromium/ui/base/clipboard/clipboard_data.h +++ b/chromium/ui/base/clipboard/clipboard_data.h @@ -20,11 +20,12 @@ namespace ui { enum class ClipboardInternalFormat { kText = 1 << 0, kHtml = 1 << 1, - kRtf = 1 << 2, - kBookmark = 1 << 3, - kBitmap = 1 << 4, - kCustom = 1 << 5, - kWeb = 1 << 6, + kSvg = 1 << 2, + kRtf = 1 << 3, + kBookmark = 1 << 4, + kBitmap = 1 << 5, + kCustom = 1 << 6, + kWeb = 1 << 7, }; // ClipboardData contains data copied to the Clipboard for a variety of formats. @@ -55,6 +56,12 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardData { format_ |= static_cast<int>(ClipboardInternalFormat::kHtml); } + const std::string& svg_data() const { return svg_data_; } + void set_svg_data(const std::string& svg_data) { + svg_data_ = svg_data; + format_ |= static_cast<int>(ClipboardInternalFormat::kSvg); + } + const std::string& rtf_data() const { return rtf_data_; } void SetRTFData(const std::string& rtf_data) { rtf_data_ = rtf_data; @@ -124,6 +131,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardData { // WebKit smart paste data. bool web_smart_paste_; + // Svg data. + std::string svg_data_; + int format_; // The source of the data. diff --git a/chromium/ui/base/clipboard/clipboard_data_endpoint.cc b/chromium/ui/base/clipboard/clipboard_data_endpoint.cc index e7160b0e0a4..8fbab3cbdbe 100644 --- a/chromium/ui/base/clipboard/clipboard_data_endpoint.cc +++ b/chromium/ui/base/clipboard/clipboard_data_endpoint.cc @@ -10,11 +10,11 @@ namespace ui { -ClipboardDataEndpoint::ClipboardDataEndpoint(const GURL& url) - : type_(EndpointType::kUrl), url_(url) {} +ClipboardDataEndpoint::ClipboardDataEndpoint(const url::Origin& origin) + : type_(EndpointType::kUrl), origin_(origin) {} ClipboardDataEndpoint::ClipboardDataEndpoint(EndpointType type) - : type_(type), url_(base::nullopt) { + : type_(type), origin_(base::nullopt) { DCHECK_NE(type, EndpointType::kUrl); } @@ -26,7 +26,7 @@ ClipboardDataEndpoint::ClipboardDataEndpoint(ClipboardDataEndpoint&& other) = bool ClipboardDataEndpoint::operator==( const ClipboardDataEndpoint& other) const { - return url_ == other.url_ && type_ == other.type_; + return origin_ == other.origin_ && type_ == other.type_; } ClipboardDataEndpoint::~ClipboardDataEndpoint() = default; diff --git a/chromium/ui/base/clipboard/clipboard_data_endpoint.h b/chromium/ui/base/clipboard/clipboard_data_endpoint.h index 787c9a0b47a..9e6f12dfd96 100644 --- a/chromium/ui/base/clipboard/clipboard_data_endpoint.h +++ b/chromium/ui/base/clipboard/clipboard_data_endpoint.h @@ -7,7 +7,7 @@ #include "base/optional.h" #include "base/stl_util.h" -#include "url/gurl.h" +#include "url/origin.h" namespace ui { @@ -15,9 +15,16 @@ namespace ui { // destination trying to read the clipboard data. // Whenever a new format is supported, a new enum should be added. enum class EndpointType { - kUrl = 0, // Website URL e.g. www.example.com - kVm = 1, // Virtual machine: ARC++, PluginVM, Crostini. - kMaxValue = kVm +#if defined(OS_CHROMEOS) || (OS_LINUX) || (OS_FUCHSIA) + kGuestOs = 0, // Guest OS: PluginVM, Crostini. +#endif // defined(OS_CHROMEOS) || (OS_LINUX) || (OS_FUCHSIA) +#if defined(OS_CHROMEOS) + kArc = 1, // ARC. +#endif // defined(OS_CHROMEOS) + kUrl = 2, // Website URL e.g. www.example.com. + kClipboardHistory = 3, // Clipboard History UI has privileged access to any + // clipboard data. + kMaxValue = kClipboardHistory }; // ClipboardDataEndpoint can represent: @@ -25,7 +32,7 @@ enum class EndpointType { // - The destination trying to access the clipboard data. class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardDataEndpoint { public: - explicit ClipboardDataEndpoint(const GURL& url); + explicit ClipboardDataEndpoint(const url::Origin& origin); // This constructor shouldn't be used if |type| == EndpointType::kUrl. explicit ClipboardDataEndpoint(EndpointType type); @@ -41,16 +48,16 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardDataEndpoint { bool IsUrlType() const { return type_ == EndpointType::kUrl; } - const GURL* url() const { return base::OptionalOrNullptr(url_); } + const url::Origin* origin() const { return base::OptionalOrNullptr(origin_); } EndpointType type() const { return type_; } private: // This variable should always have a value representing the object type. const EndpointType type_; - // The url of the data endpoint. It always has a value if |type_| == - // EndpointType::URL, otherwise it's empty. - const base::Optional<GURL> url_; + // The url::Origin of the data endpoint. It always has a value if |type_| == + // EndpointType::kUrl, otherwise it's empty. + const base::Optional<url::Origin> origin_; }; } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_data_unittest.cc b/chromium/ui/base/clipboard/clipboard_data_unittest.cc index 3d85c0cc2c3..f0a0c784736 100644 --- a/chromium/ui/base/clipboard/clipboard_data_unittest.cc +++ b/chromium/ui/base/clipboard/clipboard_data_unittest.cc @@ -9,6 +9,7 @@ #include "base/strings/string_piece_forward.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/clipboard/clipboard_data_endpoint.h" +#include "url/gurl.h" namespace ui { @@ -31,14 +32,14 @@ TEST(ClipboardDataTest, BitMapTest) { // Tests that two ClipboardData objects won't be equal if they don't have the // same data source. TEST(ClipboardDataTest, DataSrcTest) { - GURL url("www.example.com"); + url::Origin origin(url::Origin::Create(GURL("www.example.com"))); ClipboardData data1; - data1.set_source(std::make_unique<ClipboardDataEndpoint>(url)); + data1.set_source(std::make_unique<ClipboardDataEndpoint>(origin)); ClipboardData data2; EXPECT_NE(data1, data2); - data2.set_source(std::make_unique<ClipboardDataEndpoint>(url)); + data2.set_source(std::make_unique<ClipboardDataEndpoint>(origin)); EXPECT_EQ(data1, data2); } diff --git a/chromium/ui/base/clipboard/clipboard_dlp_controller.cc b/chromium/ui/base/clipboard/clipboard_dlp_controller.cc new file mode 100644 index 00000000000..5ab980182c9 --- /dev/null +++ b/chromium/ui/base/clipboard/clipboard_dlp_controller.cc @@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/clipboard/clipboard_dlp_controller.h" + +namespace ui { + +// static +ClipboardDlpController* ClipboardDlpController::Get() { + return g_clipboard_dlp_controller_; +} + +// static +void ClipboardDlpController::DeleteInstance() { + if (!g_clipboard_dlp_controller_) + return; + + delete g_clipboard_dlp_controller_; +} + +ClipboardDlpController::ClipboardDlpController() { + g_clipboard_dlp_controller_ = this; +} + +ClipboardDlpController::~ClipboardDlpController() { + g_clipboard_dlp_controller_ = nullptr; +} + +ClipboardDlpController* ClipboardDlpController::g_clipboard_dlp_controller_ = + nullptr; + +} // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_dlp_controller.h b/chromium/ui/base/clipboard/clipboard_dlp_controller.h index bf4447bf664..8fca4a43961 100644 --- a/chromium/ui/base/clipboard/clipboard_dlp_controller.h +++ b/chromium/ui/base/clipboard/clipboard_dlp_controller.h @@ -5,6 +5,7 @@ #ifndef UI_BASE_CLIPBOARD_CLIPBOARD_DLP_CONTROLLER_H_ #define UI_BASE_CLIPBOARD_CLIPBOARD_DLP_CONTROLLER_H_ +#include "base/component_export.h" #include "ui/base/clipboard/clipboard_data_endpoint.h" namespace ui { @@ -13,14 +14,27 @@ namespace ui { // read operations. It should allow/disallow clipboard data read given the // source of the data and the destination trying to access the data and a set of // rules controlling these source and destination. -class ClipboardDlpController { +class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardDlpController { public: - ClipboardDlpController() = default; - virtual ~ClipboardDlpController() = default; + // Returns a pointer to the existing instance of the class. + static ClipboardDlpController* Get(); + + // Deletes the existing instance of the class if it's already created. + // Indicates that restricting clipboard content is no longer required. + static void DeleteInstance(); virtual bool IsDataReadAllowed( const ClipboardDataEndpoint* const data_src, const ClipboardDataEndpoint* const data_dst) const = 0; + + protected: + ClipboardDlpController(); + virtual ~ClipboardDlpController(); + + private: + // A singleton of ClipboardDlpController. Equals nullptr when there's not any + // clipboard restrictions required. + static ClipboardDlpController* g_clipboard_dlp_controller_; }; } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_format_type.h b/chromium/ui/base/clipboard/clipboard_format_type.h index 17480a7d030..687a0f87ed1 100644 --- a/chromium/ui/base/clipboard/clipboard_format_type.h +++ b/chromium/ui/base/clipboard/clipboard_format_type.h @@ -55,12 +55,11 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) ClipboardFormatType { // Get format identifiers for various types. static const ClipboardFormatType& GetUrlType(); - static const ClipboardFormatType& GetMozUrlType(); static const ClipboardFormatType& GetPlainTextType(); - static const ClipboardFormatType& GetFilenameType(); static const ClipboardFormatType& GetWebKitSmartPasteType(); // Win: MS HTML Format, Other: Generic HTML format static const ClipboardFormatType& GetHtmlType(); + static const ClipboardFormatType& GetSvgType(); static const ClipboardFormatType& GetRtfType(); static const ClipboardFormatType& GetBitmapType(); // TODO(raymes): Unify web custom data and pepper custom data: @@ -83,7 +82,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) ClipboardFormatType { static const ClipboardFormatType& GetFileDescriptorType(); static const ClipboardFormatType& GetFileContentZeroType(); static const ClipboardFormatType& GetFileContentAtIndexType(LONG index); + static const ClipboardFormatType& GetFilenameType(); static const ClipboardFormatType& GetIDListType(); + static const ClipboardFormatType& GetMozUrlType(); #endif // ClipboardFormatType can be used in a set on some platforms. diff --git a/chromium/ui/base/clipboard/clipboard_format_type_android.cc b/chromium/ui/base/clipboard/clipboard_format_type_android.cc index 07564e07957..12a132edf1c 100644 --- a/chromium/ui/base/clipboard/clipboard_format_type_android.cc +++ b/chromium/ui/base/clipboard/clipboard_format_type_android.cc @@ -72,6 +72,12 @@ const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { } // static +const ClipboardFormatType& ClipboardFormatType::GetSvgType() { + static base::NoDestructor<ClipboardFormatType> type(kMimeTypeSvg); + return *type; +} + +// static const ClipboardFormatType& ClipboardFormatType::GetRtfType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeRTF); return *type; diff --git a/chromium/ui/base/clipboard/clipboard_format_type_aura.cc b/chromium/ui/base/clipboard/clipboard_format_type_aura.cc index 0ea472a7847..1d35f357e43 100644 --- a/chromium/ui/base/clipboard/clipboard_format_type_aura.cc +++ b/chromium/ui/base/clipboard/clipboard_format_type_aura.cc @@ -8,10 +8,6 @@ namespace ui { -namespace { -constexpr char kMimeTypeFilename[] = "chromium/filename"; -} - // TODO(huangdarwin): Investigate creating a new clipboard_format_type_x11 as a // wrapper around an X11 ::Atom. This wasn't possible in the past, because unit // tests spawned a new X11 server for each test, meaning Atom numeric values @@ -60,26 +56,20 @@ const ClipboardFormatType& ClipboardFormatType::GetUrlType() { } // static -const ClipboardFormatType& ClipboardFormatType::GetMozUrlType() { - static base::NoDestructor<ClipboardFormatType> type(kMimeTypeMozillaURL); - return *type; -} - -// static const ClipboardFormatType& ClipboardFormatType::GetPlainTextType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeText); return *type; } // static -const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { - static base::NoDestructor<ClipboardFormatType> type(kMimeTypeFilename); +const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { + static base::NoDestructor<ClipboardFormatType> type(kMimeTypeHTML); return *type; } // static -const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { - static base::NoDestructor<ClipboardFormatType> type(kMimeTypeHTML); +const ClipboardFormatType& ClipboardFormatType::GetSvgType() { + static base::NoDestructor<ClipboardFormatType> type(kMimeTypeSvg); return *type; } diff --git a/chromium/ui/base/clipboard/clipboard_format_type_mac.mm b/chromium/ui/base/clipboard/clipboard_format_type_mac.mm index dce0ff7dfa5..376bebae39e 100644 --- a/chromium/ui/base/clipboard/clipboard_format_type_mac.mm +++ b/chromium/ui/base/clipboard/clipboard_format_type_mac.mm @@ -76,14 +76,13 @@ const ClipboardFormatType& ClipboardFormatType::GetPlainTextType() { } // static -const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { - static base::NoDestructor<ClipboardFormatType> type(NSFilenamesPboardType); +const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { + static base::NoDestructor<ClipboardFormatType> type(NSHTMLPboardType); return *type; } -// static -const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { - static base::NoDestructor<ClipboardFormatType> type(NSHTMLPboardType); +const ClipboardFormatType& ClipboardFormatType::GetSvgType() { + static base::NoDestructor<ClipboardFormatType> type(kImageSvg); return *type; } diff --git a/chromium/ui/base/clipboard/clipboard_format_type_win.cc b/chromium/ui/base/clipboard/clipboard_format_type_win.cc index ef2e7f4c73d..b0d0a9249df 100644 --- a/chromium/ui/base/clipboard/clipboard_format_type_win.cc +++ b/chromium/ui/base/clipboard/clipboard_format_type_win.cc @@ -5,6 +5,7 @@ #include "ui/base/clipboard/clipboard_format_type.h" #include <shlobj.h> +#include <urlmon.h> #include "base/containers/flat_map.h" #include "base/memory/ptr_util.h" @@ -173,31 +174,24 @@ const ClipboardFormatType& ClipboardFormatType::GetUrlType() { } // static -const ClipboardFormatType& ClipboardFormatType::GetMozUrlType() { - static base::NoDestructor<ClipboardFormatType> format( - ::RegisterClipboardFormat(L"text/x-moz-url")); - return *format; -} - -// static const ClipboardFormatType& ClipboardFormatType::GetPlainTextType() { static base::NoDestructor<ClipboardFormatType> format(CF_UNICODETEXT); return *format; } +// MS HTML Format + // static -const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { +const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { static base::NoDestructor<ClipboardFormatType> format( - ::RegisterClipboardFormat(CFSTR_FILENAMEW)); + ::RegisterClipboardFormat(L"HTML Format")); return *format; } -// MS HTML Format - // static -const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { +const ClipboardFormatType& ClipboardFormatType::GetSvgType() { static base::NoDestructor<ClipboardFormatType> format( - ::RegisterClipboardFormat(L"HTML Format")); + ::RegisterClipboardFormat(CFSTR_MIME_SVG_XML)); return *format; } @@ -304,6 +298,13 @@ const ClipboardFormatType& ClipboardFormatType::GetFileContentAtIndexType( } // static +const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { + static base::NoDestructor<ClipboardFormatType> format( + ::RegisterClipboardFormat(CFSTR_FILENAMEW)); + return *format; +} + +// static const ClipboardFormatType& ClipboardFormatType::GetIDListType() { static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(CFSTR_SHELLIDLIST)); @@ -311,6 +312,13 @@ const ClipboardFormatType& ClipboardFormatType::GetIDListType() { } // static +const ClipboardFormatType& ClipboardFormatType::GetMozUrlType() { + static base::NoDestructor<ClipboardFormatType> format( + ::RegisterClipboardFormat(L"text/x-moz-url")); + return *format; +} + +// static const ClipboardFormatType& ClipboardFormatType::GetWebKitSmartPasteType() { static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(L"WebKit Smart Paste Format")); diff --git a/chromium/ui/base/clipboard/clipboard_mac.h b/chromium/ui/base/clipboard/clipboard_mac.h index 1189e05278c..f220aa72ca4 100644 --- a/chromium/ui/base/clipboard/clipboard_mac.h +++ b/chromium/ui/base/clipboard/clipboard_mac.h @@ -31,8 +31,6 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardMac : public Clipboard { // Clipboard overrides: void OnPreShutdown() override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const override; @@ -57,6 +55,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardMac : public Clipboard { std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -86,6 +87,7 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardMac : public Clipboard { size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/clipboard_mac.mm b/chromium/ui/base/clipboard/clipboard_mac.mm index 3faea41c500..2eb361f4f0e 100644 --- a/chromium/ui/base/clipboard/clipboard_mac.mm +++ b/chromium/ui/base/clipboard/clipboard_mac.mm @@ -70,11 +70,6 @@ uint64_t ClipboardMac::GetSequenceNumber(ClipboardBuffer buffer) const { return [pb changeCount]; } -void ClipboardMac::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - NOTIMPLEMENTED(); -} - // |data_dst| is not used. It's only passed to be consistent with other // platforms. bool ClipboardMac::IsFormatAvailable( @@ -140,6 +135,8 @@ void ClipboardMac::ReadAvailableTypes( types->push_back(base::UTF8ToUTF16(kMimeTypeText)); if (IsFormatAvailable(ClipboardFormatType::GetHtmlType(), buffer, data_dst)) types->push_back(base::UTF8ToUTF16(kMimeTypeHTML)); + if (IsFormatAvailable(ClipboardFormatType::GetSvgType(), buffer, data_dst)) + types->push_back(base::UTF8ToUTF16(kMimeTypeSvg)); if (IsFormatAvailable(ClipboardFormatType::GetRtfType(), buffer, data_dst)) types->push_back(base::UTF8ToUTF16(kMimeTypeRTF)); @@ -239,6 +236,18 @@ void ClipboardMac::ReadHTML(ClipboardBuffer buffer, *fragment_end = static_cast<uint32_t>(markup->length()); } +void ClipboardMac::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); + RecordRead(ClipboardFormatMetric::kSvg); + NSPasteboard* pb = GetPasteboard(); + NSString* contents = [pb stringForType:kImageSvg]; + + *result = base::SysNSStringToUTF16(contents); +} + // |data_dst| is not used. It's only passed to be consistent with other // platforms. void ClipboardMac::ReadRTF(ClipboardBuffer buffer, @@ -368,6 +377,14 @@ void ClipboardMac::WriteHTML(const char* markup_data, [pb setString:html_fragment forType:NSHTMLPboardType]; } +void ClipboardMac::WriteSvg(const char* markup_data, size_t markup_len) { + std::string svg_str(markup_data, markup_len); + NSString* svg = base::SysUTF8ToNSString(svg_str); + NSPasteboard* pb = GetPasteboard(); + [pb addTypes:@[ kImageSvg ] owner:nil]; + [pb setString:svg forType:kImageSvg]; +} + void ClipboardMac::WriteRTF(const char* rtf_data, size_t data_len) { WriteData(ClipboardFormatType::GetRtfType(), rtf_data, data_len); } diff --git a/chromium/ui/base/clipboard/clipboard_metrics.h b/chromium/ui/base/clipboard/clipboard_metrics.h index 5077043bafe..e7194491b4d 100644 --- a/chromium/ui/base/clipboard/clipboard_metrics.h +++ b/chromium/ui/base/clipboard/clipboard_metrics.h @@ -19,7 +19,8 @@ enum class ClipboardFormatMetric { kData = 5, kCustomData = 6, kWebSmartPaste = 7, // Only used on write. - kMaxValue = kWebSmartPaste, + kSvg = 8, + kMaxValue = kSvg, }; void RecordRead(ClipboardFormatMetric metric); diff --git a/chromium/ui/base/clipboard/clipboard_monitor.cc b/chromium/ui/base/clipboard/clipboard_monitor.cc index b8bd0944d8a..1d5cd5518d9 100644 --- a/chromium/ui/base/clipboard/clipboard_monitor.cc +++ b/chromium/ui/base/clipboard/clipboard_monitor.cc @@ -27,6 +27,14 @@ void ClipboardMonitor::NotifyClipboardDataChanged() { observer.OnClipboardDataChanged(); } +#if defined(OS_CHROMEOS) +void ClipboardMonitor::NotifyClipboardDataRead() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + for (ClipboardObserver& observer : observers_) + observer.OnClipboardDataRead(); +} +#endif + void ClipboardMonitor::AddObserver(ClipboardObserver* observer) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); observers_.AddObserver(observer); diff --git a/chromium/ui/base/clipboard/clipboard_monitor.h b/chromium/ui/base/clipboard/clipboard_monitor.h index a1711f2aee1..d09aafaaec7 100644 --- a/chromium/ui/base/clipboard/clipboard_monitor.h +++ b/chromium/ui/base/clipboard/clipboard_monitor.h @@ -10,6 +10,7 @@ #include "base/no_destructor.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" +#include "build/build_config.h" namespace ui { @@ -30,6 +31,11 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardMonitor { // Notifies all observers for clipboard data change. virtual void NotifyClipboardDataChanged(); +#if defined(OS_CHROMEOS) + // Notifies all observers for clipboard data read. + virtual void NotifyClipboardDataRead(); +#endif + private: friend class base::NoDestructor<ClipboardMonitor>; diff --git a/chromium/ui/base/clipboard/clipboard_non_backed.cc b/chromium/ui/base/clipboard/clipboard_non_backed.cc index 31cf5d946b1..a53ca0a33d1 100644 --- a/chromium/ui/base/clipboard/clipboard_non_backed.cc +++ b/chromium/ui/base/clipboard/clipboard_non_backed.cc @@ -154,6 +154,19 @@ class ClipboardInternal { *fragment_end = static_cast<uint32_t>(markup->length()); } + // Reads SVG from the ClipboardData. + void ReadSvg(base::string16* markup) const { + markup->clear(); + + if (!HasFormat(ClipboardInternalFormat::kSvg)) + return; + + const ClipboardData* data = GetData(); + *markup = base::UTF8ToUTF16(data->svg_data()); + + DCHECK_LE(markup->length(), std::numeric_limits<uint32_t>::max()); + } + // Reads RTF from the ClipboardData. void ReadRTF(std::string* result) const { result->clear(); @@ -213,7 +226,6 @@ class ClipboardInternal { if (!HasFormat(ClipboardInternalFormat::kCustom) || type != data->custom_data_format()) return; - *result = data->custom_data_data(); } @@ -228,15 +240,12 @@ class ClipboardInternal { return previous_data; } - void SetDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - dlp_controller_ = std::move(dlp_controller); - } - bool IsReadAllowed(const ClipboardDataEndpoint* data_dst) const { - if (!dlp_controller_) + ClipboardDlpController* dlp_controller = ClipboardDlpController::Get(); + auto* data = GetData(); + if (!dlp_controller || !data) return true; - return dlp_controller_->IsDataReadAllowed(GetData()->source(), data_dst); + return dlp_controller->IsDataReadAllowed(data->source(), data_dst); } private: @@ -252,9 +261,6 @@ class ClipboardInternal { // Sequence number uniquely identifying clipboard state. uint64_t sequence_number_ = 0; - // Data-leak prevention controller controlling clipboard read operations. - std::unique_ptr<ClipboardDlpController> dlp_controller_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(ClipboardInternal); }; @@ -285,6 +291,11 @@ class ClipboardDataBuilder { data->set_url(std::string(url_data, url_len)); } + static void WriteSvg(const char* markup_data, size_t markup_len) { + ClipboardData* data = GetCurrentData(); + data->set_svg_data(std::string(markup_data, markup_len)); + } + static void WriteRTF(const char* rtf_data, size_t rtf_len) { ClipboardData* data = GetCurrentData(); data->SetRTFData(std::string(rtf_data, rtf_len)); @@ -363,8 +374,13 @@ ClipboardNonBacked::~ClipboardNonBacked() { UnregisterInstance(this); } -const ClipboardData* ClipboardNonBacked::GetClipboardData() const { +const ClipboardData* ClipboardNonBacked::GetClipboardData( + ClipboardDataEndpoint* data_dst) const { DCHECK(CalledOnValidThread()); + + if (!clipboard_internal_->IsReadAllowed(data_dst)) + return nullptr; + return clipboard_internal_->GetData(); } @@ -376,11 +392,6 @@ std::unique_ptr<ClipboardData> ClipboardNonBacked::WriteClipboardData( void ClipboardNonBacked::OnPreShutdown() {} -void ClipboardNonBacked::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - clipboard_internal_->SetDlpController(std::move(dlp_controller)); -} - uint64_t ClipboardNonBacked::GetSequenceNumber(ClipboardBuffer buffer) const { DCHECK(CalledOnValidThread()); return clipboard_internal_->sequence_number(); @@ -403,6 +414,9 @@ bool ClipboardNonBacked::IsFormatAvailable( if (format == ClipboardFormatType::GetHtmlType()) return clipboard_internal_->IsFormatAvailable( ClipboardInternalFormat::kHtml); + if (format == ClipboardFormatType::GetSvgType()) + return clipboard_internal_->IsFormatAvailable( + ClipboardInternalFormat::kSvg); if (format == ClipboardFormatType::GetRtfType()) return clipboard_internal_->IsFormatAvailable( ClipboardInternalFormat::kRtf); @@ -498,6 +512,10 @@ void ClipboardNonBacked::ReadText(ClipboardBuffer buffer, RecordRead(ClipboardFormatMetric::kText); clipboard_internal_->ReadText(result); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadAsciiText(ClipboardBuffer buffer, @@ -510,6 +528,10 @@ void ClipboardNonBacked::ReadAsciiText(ClipboardBuffer buffer, RecordRead(ClipboardFormatMetric::kText); clipboard_internal_->ReadAsciiText(result); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadHTML(ClipboardBuffer buffer, @@ -525,6 +547,22 @@ void ClipboardNonBacked::ReadHTML(ClipboardBuffer buffer, RecordRead(ClipboardFormatMetric::kHtml); clipboard_internal_->ReadHTML(markup, src_url, fragment_start, fragment_end); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif +} + +void ClipboardNonBacked::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK(CalledOnValidThread()); + + if (!clipboard_internal_->IsReadAllowed(data_dst)) + return; + + RecordRead(ClipboardFormatMetric::kSvg); + clipboard_internal_->ReadSvg(result); } void ClipboardNonBacked::ReadRTF(ClipboardBuffer buffer, @@ -537,6 +575,10 @@ void ClipboardNonBacked::ReadRTF(ClipboardBuffer buffer, RecordRead(ClipboardFormatMetric::kRtf); clipboard_internal_->ReadRTF(result); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadImage(ClipboardBuffer buffer, @@ -544,11 +586,17 @@ void ClipboardNonBacked::ReadImage(ClipboardBuffer buffer, ReadImageCallback callback) const { DCHECK(CalledOnValidThread()); - if (!clipboard_internal_->IsReadAllowed(data_dst)) + if (!clipboard_internal_->IsReadAllowed(data_dst)) { + std::move(callback).Run(SkBitmap()); return; + } RecordRead(ClipboardFormatMetric::kImage); std::move(callback).Run(clipboard_internal_->ReadImage()); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadCustomData(ClipboardBuffer buffer, @@ -562,6 +610,10 @@ void ClipboardNonBacked::ReadCustomData(ClipboardBuffer buffer, RecordRead(ClipboardFormatMetric::kCustomData); clipboard_internal_->ReadCustomData(type, result); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadBookmark(const ClipboardDataEndpoint* data_dst, @@ -574,6 +626,10 @@ void ClipboardNonBacked::ReadBookmark(const ClipboardDataEndpoint* data_dst, RecordRead(ClipboardFormatMetric::kBookmark); clipboard_internal_->ReadBookmark(title, url); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } void ClipboardNonBacked::ReadData(const ClipboardFormatType& format, @@ -586,6 +642,10 @@ void ClipboardNonBacked::ReadData(const ClipboardFormatType& format, RecordRead(ClipboardFormatMetric::kData); clipboard_internal_->ReadData(format.GetName(), result); + +#if defined(OS_CHROMEOS) + ClipboardMonitor::GetInstance()->NotifyClipboardDataRead(); +#endif } bool ClipboardNonBacked::IsSelectionBufferAvailable() const { @@ -628,6 +688,10 @@ void ClipboardNonBacked::WriteHTML(const char* markup_data, ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len); } +void ClipboardNonBacked::WriteSvg(const char* markup_data, size_t markup_len) { + ClipboardDataBuilder::WriteSvg(markup_data, markup_len); +} + void ClipboardNonBacked::WriteRTF(const char* rtf_data, size_t data_len) { ClipboardDataBuilder::WriteRTF(rtf_data, data_len); } diff --git a/chromium/ui/base/clipboard/clipboard_non_backed.h b/chromium/ui/base/clipboard/clipboard_non_backed.h index c66c814964f..76dee9c24ed 100644 --- a/chromium/ui/base/clipboard/clipboard_non_backed.h +++ b/chromium/ui/base/clipboard/clipboard_non_backed.h @@ -32,9 +32,10 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked static ClipboardNonBacked* GetForCurrentThread(); // Returns the current ClipboardData. - const ClipboardData* GetClipboardData() const; + const ClipboardData* GetClipboardData(ClipboardDataEndpoint* data_dst) const; // Writes the current ClipboardData and returns the previous data. + // The data source is expected to be set in `data`. std::unique_ptr<ClipboardData> WriteClipboardData( std::unique_ptr<ClipboardData> data); @@ -46,8 +47,6 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked // Clipboard overrides: void OnPreShutdown() override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, @@ -71,6 +70,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -101,6 +103,7 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/clipboard_non_backed_unittest.cc b/chromium/ui/base/clipboard/clipboard_non_backed_unittest.cc index 30a411f56fd..4fa7c18928a 100644 --- a/chromium/ui/base/clipboard/clipboard_non_backed_unittest.cc +++ b/chromium/ui/base/clipboard/clipboard_non_backed_unittest.cc @@ -6,6 +6,7 @@ #include <memory> +#include "base/test/metrics/histogram_tester.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/clipboard/clipboard_data.h" @@ -31,7 +32,7 @@ TEST_F(ClipboardNonBackedTest, WriteAndGetClipboardData) { auto* expected_clipboard_data_ptr = clipboard_data.get(); clipboard()->WriteClipboardData(std::move(clipboard_data)); - auto* actual_clipboard_data_ptr = clipboard()->GetClipboardData(); + auto* actual_clipboard_data_ptr = clipboard()->GetClipboardData(nullptr); EXPECT_EQ(expected_clipboard_data_ptr, actual_clipboard_data_ptr); } @@ -51,7 +52,26 @@ TEST_F(ClipboardNonBackedTest, WriteClipboardData) { previous_data = clipboard()->WriteClipboardData(std::move(second_data)); EXPECT_EQ(first_data_ptr, previous_data.get()); - EXPECT_EQ(second_data_ptr, clipboard()->GetClipboardData()); + EXPECT_EQ(second_data_ptr, clipboard()->GetClipboardData(nullptr)); +} + +// Verifies that directly writing to ClipboardInternal does not result in +// histograms being logged. This is used by ClipboardHistoryController to +// manipulate the clipboard in order to facilitate pasting from clipboard +// history. +TEST_F(ClipboardNonBackedTest, AdminWriteDoesNotRecordHistograms) { + base::HistogramTester histogram_tester; + auto data = std::make_unique<ClipboardData>(); + data->set_text("test"); + + auto* data_ptr = data.get(); + + // Write the data to the clipboard, no histograms should be recorded. + clipboard()->WriteClipboardData(std::move(data)); + EXPECT_EQ(data_ptr, clipboard()->GetClipboardData(/*data_dst=*/nullptr)); + + histogram_tester.ExpectTotalCount("Clipboard.Read", 0); + histogram_tester.ExpectTotalCount("Clipboard.Write", 0); } } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_observer.cc b/chromium/ui/base/clipboard/clipboard_observer.cc new file mode 100644 index 00000000000..4adb0ac9954 --- /dev/null +++ b/chromium/ui/base/clipboard/clipboard_observer.cc @@ -0,0 +1,17 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/clipboard/clipboard_observer.h" + +namespace ui { + +void ClipboardObserver::OnClipboardDataChanged() {} + +#if defined(OS_CHROMEOS) +void ClipboardObserver::OnClipboardDataRead() {} +#endif + +ClipboardObserver::~ClipboardObserver() = default; + +} // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_observer.h b/chromium/ui/base/clipboard/clipboard_observer.h index d6305817699..3e3a2af7c94 100644 --- a/chromium/ui/base/clipboard/clipboard_observer.h +++ b/chromium/ui/base/clipboard/clipboard_observer.h @@ -7,17 +7,23 @@ #include "base/component_export.h" #include "base/macros.h" +#include "build/build_config.h" namespace ui { -// Observer that receives the notifications of clipboard change events. +// Observer that receives the notifications of clipboard events. class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardObserver { public: - // Called when clipboard data is changed. - virtual void OnClipboardDataChanged() = 0; + // Override notified when clipboard data is changed. + virtual void OnClipboardDataChanged(); + +#if defined(OS_CHROMEOS) + // Override notified when clipboard data is read. + virtual void OnClipboardDataRead(); +#endif protected: - virtual ~ClipboardObserver() = default; + virtual ~ClipboardObserver(); }; } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_ozone.cc b/chromium/ui/base/clipboard/clipboard_ozone.cc index 5f46a6215cb..4c97d862b6f 100644 --- a/chromium/ui/base/clipboard/clipboard_ozone.cc +++ b/chromium/ui/base/clipboard/clipboard_ozone.cc @@ -347,12 +347,6 @@ uint64_t ClipboardOzone::GetSequenceNumber(ClipboardBuffer buffer) const { return async_clipboard_ozone_->GetSequenceNumber(buffer); } -// TODO(crbug.com/1103194): Setting |dlp_controller| should be supported. -void ClipboardOzone::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - NOTIMPLEMENTED(); -} - // TODO(crbug.com/1103194): |data_dst| should be supported. bool ClipboardOzone::IsFormatAvailable( const ClipboardFormatType& format, @@ -459,6 +453,19 @@ void ClipboardOzone::ReadHTML(ClipboardBuffer buffer, } // TODO(crbug.com/1103194): |data_dst| should be supported. +void ClipboardOzone::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK(CalledOnValidThread()); + RecordRead(ClipboardFormatMetric::kSvg); + + auto clipboard_data = + async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeSvg); + *result = base::UTF8ToUTF16(base::StringPiece( + reinterpret_cast<char*>(clipboard_data.data()), clipboard_data.size())); +} + +// TODO(crbug.com/1103194): |data_dst| should be supported. void ClipboardOzone::ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const { @@ -570,6 +577,11 @@ void ClipboardOzone::WriteHTML(const char* markup_data, async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeHTML}); } +void ClipboardOzone::WriteSvg(const char* markup_data, size_t markup_len) { + std::vector<uint8_t> data(markup_data, markup_data + markup_len); + async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeSvg}); +} + void ClipboardOzone::WriteRTF(const char* rtf_data, size_t data_len) { std::vector<uint8_t> data(rtf_data, rtf_data + data_len); async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeRTF}); diff --git a/chromium/ui/base/clipboard/clipboard_ozone.h b/chromium/ui/base/clipboard/clipboard_ozone.h index c254b022989..43f7b5c2651 100644 --- a/chromium/ui/base/clipboard/clipboard_ozone.h +++ b/chromium/ui/base/clipboard/clipboard_ozone.h @@ -26,8 +26,6 @@ class ClipboardOzone : public Clipboard { // Clipboard overrides: void OnPreShutdown() override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const override; @@ -50,6 +48,9 @@ class ClipboardOzone : public Clipboard { std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -80,6 +81,7 @@ class ClipboardOzone : public Clipboard { size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/clipboard_test_template.h b/chromium/ui/base/clipboard/clipboard_test_template.h index c165e64fa6d..62eb2afe262 100644 --- a/chromium/ui/base/clipboard/clipboard_test_template.h +++ b/chromium/ui/base/clipboard/clipboard_test_template.h @@ -28,7 +28,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/lacros_buildflags.h" +#include "build/chromeos_buildflags.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -46,12 +46,13 @@ #include "ui/base/clipboard/test/test_clipboard.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/half_float.h" +#include "url/origin.h" #if defined(OS_WIN) #include "ui/base/clipboard/clipboard_util_win.h" #endif -#if defined(USE_X11) +#if defined(USE_X11) || defined(USE_OZONE) #include "ui/base/ui_base_features.h" #include "ui/events/platform/platform_event_source.h" #endif @@ -64,8 +65,6 @@ using testing::Contains; namespace ui { -class MockClipboardDlpController; - template <typename ClipboardTraits> class ClipboardTest : public PlatformTest { public: @@ -96,36 +95,33 @@ class ClipboardTest : public PlatformTest { return types; } - void AddDlpController() { - auto dlp_controller = std::make_unique<MockClipboardDlpController>(); - dlp_controller_ = dlp_controller.get(); - ClipboardTest::clipboard().SetClipboardDlpController( - std::move(dlp_controller)); - } - - MockClipboardDlpController* dlp_controller() const { return dlp_controller_; } - private: #if defined(USE_X11) std::unique_ptr<PlatformEventSource> event_source_; #endif // Clipboard has a protected destructor, so scoped_ptr doesn't work here. Clipboard* clipboard_ = nullptr; - - // MockClipboardDlpController object is owned by ClipboardTest. - MockClipboardDlpController* dlp_controller_ = nullptr; }; // A mock delegate for testing. class MockClipboardDlpController : public ClipboardDlpController { public: - MockClipboardDlpController(); - ~MockClipboardDlpController(); + static MockClipboardDlpController* Init(); + MOCK_CONST_METHOD2(IsDataReadAllowed, bool(const ClipboardDataEndpoint* const data_src, const ClipboardDataEndpoint* const data_dst)); + + private: + MockClipboardDlpController(); + ~MockClipboardDlpController() override; }; +// static +MockClipboardDlpController* MockClipboardDlpController::Init() { + return new MockClipboardDlpController(); +} + MockClipboardDlpController::MockClipboardDlpController() = default; MockClipboardDlpController::~MockClipboardDlpController() = default; @@ -171,8 +167,12 @@ TYPED_TEST(ClipboardTest, TextTest) { Contains(ASCIIToUTF16(kMimeTypeText))); #if defined(USE_OZONE) && !defined(OS_CHROMEOS) && !defined(OS_FUCHSIA) && \ !BUILDFLAG(IS_CHROMECAST) && !BUILDFLAG(IS_LACROS) - EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), - Contains(ASCIIToUTF16(kMimeTypeTextUtf8))); + // TODO(https://crbug.com/1096425): remove this if condition. It seems like + // we have this condition working for Ozone/Linux, but not for X11/Linux. + if (features::IsUsingOzonePlatform()) { + EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), + Contains(ASCIIToUTF16(kMimeTypeTextUtf8))); + } #endif EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste, @@ -223,6 +223,25 @@ TYPED_TEST(ClipboardTest, HTMLTest) { #endif // defined(OS_WIN) } +TYPED_TEST(ClipboardTest, SvgTest) { + base::string16 markup(ASCIIToUTF16("<svg> <circle r=\"40\" /> </svg>")); + + { + ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste); + clipboard_writer.WriteSvg(markup); + } + + EXPECT_TRUE(this->clipboard().IsFormatAvailable( + ClipboardFormatType::GetSvgType(), ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr)); + + base::string16 markup_result; + this->clipboard().ReadSvg(ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr, &markup_result); + + EXPECT_EQ(markup, markup_result); +} + #if !defined(OS_ANDROID) // TODO(crbug/1064968): This test fails with ClipboardAndroid, but passes with // the TestClipboard as RTF isn't implemented in ClipboardAndroid. @@ -1031,6 +1050,11 @@ TYPED_TEST(ClipboardTest, WriteHTMLEmptyParams) { scw.WriteHTML(base::string16(), std::string()); } +TYPED_TEST(ClipboardTest, EmptySvgTest) { + ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste); + clipboard_writer.WriteSvg(base::string16()); +} + TYPED_TEST(ClipboardTest, WriteRTFEmptyParams) { ScopedClipboardWriter scw(ClipboardBuffer::kCopyPaste); scw.WriteRTF(std::string()); @@ -1062,15 +1086,14 @@ TYPED_TEST(ClipboardTest, WriteImageEmptyParams) { // Test that copy/paste would work normally if the dlp controller didn't // restrict the clipboard data. TYPED_TEST(ClipboardTest, DlpAllowDataRead) { - this->AddDlpController(); + auto* dlp_controller = MockClipboardDlpController::Init(); const base::string16 kTestText(base::UTF8ToUTF16("World")); { ScopedClipboardWriter writer( ClipboardBuffer::kCopyPaste, - std::make_unique<ClipboardDataEndpoint>(GURL())); + std::make_unique<ClipboardDataEndpoint>(url::Origin())); writer.WriteText(kTestText); } - auto* dlp_controller = this->dlp_controller(); EXPECT_CALL(*dlp_controller, IsDataReadAllowed) .WillRepeatedly(testing::Return(true)); base::string16 read_result; @@ -1078,20 +1101,20 @@ TYPED_TEST(ClipboardTest, DlpAllowDataRead) { /* data_dst = */ nullptr, &read_result); ::testing::Mock::VerifyAndClearExpectations(dlp_controller); EXPECT_EQ(kTestText, read_result); + MockClipboardDlpController::DeleteInstance(); } // Test that pasting clipboard data would not work if the dlp controller // restricted it. -TYPED_TEST(ClipboardTest, DlpDisallowDataRead) { - this->AddDlpController(); +TYPED_TEST(ClipboardTest, DlpDisallow_ReadText) { + auto* dlp_controller = MockClipboardDlpController::Init(); const base::string16 kTestText(base::UTF8ToUTF16("World")); { ScopedClipboardWriter writer( ClipboardBuffer::kCopyPaste, - std::make_unique<ClipboardDataEndpoint>(GURL())); + std::make_unique<ClipboardDataEndpoint>(url::Origin())); writer.WriteText(kTestText); } - auto* dlp_controller = this->dlp_controller(); EXPECT_CALL(*dlp_controller, IsDataReadAllowed) .WillRepeatedly(testing::Return(false)); base::string16 read_result; @@ -1099,7 +1122,19 @@ TYPED_TEST(ClipboardTest, DlpDisallowDataRead) { /* data_dst = */ nullptr, &read_result); ::testing::Mock::VerifyAndClearExpectations(dlp_controller); EXPECT_EQ(base::string16(), read_result); + MockClipboardDlpController::DeleteInstance(); +} + +TYPED_TEST(ClipboardTest, DlpDisallow_ReadImage) { + auto* dlp_controller = MockClipboardDlpController::Init(); + EXPECT_CALL(*dlp_controller, IsDataReadAllowed) + .WillRepeatedly(testing::Return(false)); + const SkBitmap& image = clipboard_test_util::ReadImage(&this->clipboard()); + ::testing::Mock::VerifyAndClearExpectations(dlp_controller); + EXPECT_EQ(true, image.empty()); + MockClipboardDlpController::DeleteInstance(); } + #endif // defined(OS_CHROMEOS) } // namespace ui diff --git a/chromium/ui/base/clipboard/clipboard_win.cc b/chromium/ui/base/clipboard/clipboard_win.cc index b422119ff36..8d0e981720b 100644 --- a/chromium/ui/base/clipboard/clipboard_win.cc +++ b/chromium/ui/base/clipboard/clipboard_win.cc @@ -246,11 +246,6 @@ uint64_t ClipboardWin::GetSequenceNumber(ClipboardBuffer buffer) const { return ::GetClipboardSequenceNumber(); } -void ClipboardWin::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - NOTIMPLEMENTED(); -} - // |data_dst| is not used. It's only passed to be consistent with other // platforms. bool ClipboardWin::IsFormatAvailable( @@ -454,6 +449,22 @@ void ClipboardWin::ReadHTML(ClipboardBuffer buffer, // |data_dst| is not used. It's only passed to be consistent with other // platforms. +void ClipboardWin::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); + RecordRead(ClipboardFormatMetric::kSvg); + + std::string data; + ReadData(ClipboardFormatType::GetSvgType(), data_dst, &data); + result->assign(reinterpret_cast<const base::char16*>(data.data()), + data.size() / sizeof(base::char16)); + + TrimAfterNull(result); +} + +// |data_dst| is not used. It's only passed to be consistent with other +// platforms. void ClipboardWin::ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const { @@ -609,6 +620,14 @@ void ClipboardWin::WriteHTML(const char* markup_data, WriteToClipboard(ClipboardFormatType::GetHtmlType(), glob); } +void ClipboardWin::WriteSvg(const char* markup_data, size_t markup_len) { + base::string16 markup; + base::UTF8ToUTF16(markup_data, markup_len, &markup); + HGLOBAL glob = CreateGlobalData(markup); + + WriteToClipboard(ClipboardFormatType::GetSvgType(), glob); +} + void ClipboardWin::WriteRTF(const char* rtf_data, size_t data_len) { WriteData(ClipboardFormatType::GetRtfType(), rtf_data, data_len); } diff --git a/chromium/ui/base/clipboard/clipboard_win.h b/chromium/ui/base/clipboard/clipboard_win.h index 32e85b07d16..8fbe2722bff 100644 --- a/chromium/ui/base/clipboard/clipboard_win.h +++ b/chromium/ui/base/clipboard/clipboard_win.h @@ -36,8 +36,6 @@ class ClipboardWin : public Clipboard { // Clipboard overrides: void OnPreShutdown() override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const override; @@ -60,6 +58,9 @@ class ClipboardWin : public Clipboard { std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -89,6 +90,7 @@ class ClipboardWin : public Clipboard { size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/clipboard_x11.cc b/chromium/ui/base/clipboard/clipboard_x11.cc index 71b5489dafd..a1fbfcae549 100644 --- a/chromium/ui/base/clipboard/clipboard_x11.cc +++ b/chromium/ui/base/clipboard/clipboard_x11.cc @@ -271,8 +271,8 @@ ClipboardX11::X11Details::X11Details() primary_owner_(connection_, x_window_, x11::Atom::PRIMARY) { SetStringProperty(x_window_, x11::Atom::WM_NAME, x11::Atom::STRING, "Chromium clipboard"); - x_window_events_ = - std::make_unique<XScopedEventSelector>(x_window_, PropertyChangeMask); + x_window_events_ = std::make_unique<XScopedEventSelector>( + x_window_, x11::EventMask::PropertyChange); if (X11EventSource::GetInstance()) X11EventSource::GetInstance()->AddXEventDispatcher(this); @@ -496,11 +496,6 @@ uint64_t ClipboardX11::GetSequenceNumber(ClipboardBuffer buffer) const { return SelectionChangeObserver::GetInstance()->primary_sequence_number(); } -void ClipboardX11::SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) { - NOTIMPLEMENTED(); -} - // |data_dst| is not used. It's only passed to be consistent with other // platforms. bool ClipboardX11::IsFormatAvailable( @@ -644,6 +639,24 @@ void ClipboardX11::ReadHTML(ClipboardBuffer buffer, // |data_dst| is not used. It's only passed to be consistent with other // platforms. +void ClipboardX11::ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const { + DCHECK(CalledOnValidThread()); + RecordRead(ClipboardFormatMetric::kSvg); + + SelectionData data(x11_details_->RequestAndWaitForTypes( + buffer, + x11_details_->GetAtomsForFormat(ClipboardFormatType::GetSvgType()))); + if (data.IsValid()) { + std::string markup; + data.AssignTo(&markup); + *result = base::UTF8ToUTF16(markup); + } +} + +// |data_dst| is not used. It's only passed to be consistent with other +// platforms. void ClipboardX11::ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const { @@ -785,6 +798,14 @@ void ClipboardX11::WriteHTML(const char* markup_data, x11_details_->InsertMapping(kMimeTypeHTML, mem); } +void ClipboardX11::WriteSvg(const char* markup_data, size_t markup_len) { + std::string str(markup_data, markup_len); + scoped_refptr<base::RefCountedMemory> mem( + base::RefCountedString::TakeString(&str)); + + x11_details_->InsertMapping(kMimeTypeSvg, mem); +} + void ClipboardX11::WriteRTF(const char* rtf_data, size_t data_len) { WriteData(ClipboardFormatType::GetRtfType(), rtf_data, data_len); } diff --git a/chromium/ui/base/clipboard/clipboard_x11.h b/chromium/ui/base/clipboard/clipboard_x11.h index 9143b11d3f9..cae0a85a29b 100644 --- a/chromium/ui/base/clipboard/clipboard_x11.h +++ b/chromium/ui/base/clipboard/clipboard_x11.h @@ -25,8 +25,6 @@ class ClipboardX11 : public Clipboard { // Clipboard overrides: void OnPreShutdown() override; uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override; - void SetClipboardDlpController( - std::unique_ptr<ClipboardDlpController> dlp_controller) override; bool IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst) const override; @@ -49,6 +47,9 @@ class ClipboardX11 : public Clipboard { std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const override; + void ReadSvg(ClipboardBuffer buffer, + const ClipboardDataEndpoint* data_dst, + base::string16* result) const override; void ReadRTF(ClipboardBuffer buffer, const ClipboardDataEndpoint* data_dst, std::string* result) const override; @@ -81,6 +82,7 @@ class ClipboardX11 : public Clipboard { size_t markup_len, const char* url_data, size_t url_len) override; + void WriteSvg(const char* markup_data, size_t markup_len) override; void WriteRTF(const char* rtf_data, size_t data_len) override; void WriteBookmark(const char* title_data, size_t title_len, diff --git a/chromium/ui/base/clipboard/scoped_clipboard_writer.cc b/chromium/ui/base/clipboard/scoped_clipboard_writer.cc index 2a806d3010f..b43743e28ff 100644 --- a/chromium/ui/base/clipboard/scoped_clipboard_writer.cc +++ b/chromium/ui/base/clipboard/scoped_clipboard_writer.cc @@ -67,6 +67,16 @@ void ScopedClipboardWriter::WriteHTML(const base::string16& markup, objects_[Clipboard::PortableFormat::kHtml] = parameters; } +void ScopedClipboardWriter::WriteSvg(const base::string16& markup) { + RecordWrite(ClipboardFormatMetric::kSvg); + std::string utf8_markup = base::UTF16ToUTF8(markup); + + Clipboard::ObjectMapParams parameters; + parameters.push_back( + Clipboard::ObjectMapParam(utf8_markup.begin(), utf8_markup.end())); + objects_[Clipboard::PortableFormat::kSvg] = parameters; +} + void ScopedClipboardWriter::WriteRTF(const std::string& rtf_data) { RecordWrite(ClipboardFormatMetric::kRtf); Clipboard::ObjectMapParams parameters; diff --git a/chromium/ui/base/clipboard/scoped_clipboard_writer.h b/chromium/ui/base/clipboard/scoped_clipboard_writer.h index 82bf6526076..bac40ada9ee 100644 --- a/chromium/ui/base/clipboard/scoped_clipboard_writer.h +++ b/chromium/ui/base/clipboard/scoped_clipboard_writer.h @@ -47,6 +47,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter { // useful if the HTML fragment contains relative links. void WriteHTML(const base::string16& markup, const std::string& source_url); + // Adds SVG to the clipboard. + void WriteSvg(const base::string16& text); + // Adds RTF to the clipboard. void WriteRTF(const std::string& rtf_data); |