summaryrefslogtreecommitdiff
path: root/chromium/ui/base/clipboard
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/base/clipboard')
-rw-r--r--chromium/ui/base/clipboard/BUILD.gn72
-rw-r--r--chromium/ui/base/clipboard/clipboard.cc6
-rw-r--r--chromium/ui/base/clipboard/clipboard.h11
-rw-r--r--chromium/ui/base/clipboard/clipboard_android.cc11
-rw-r--r--chromium/ui/base/clipboard/clipboard_constants.h7
-rw-r--r--chromium/ui/base/clipboard/clipboard_constants_mac.mm5
-rw-r--r--chromium/ui/base/clipboard/clipboard_linux.cc33
-rw-r--r--chromium/ui/base/clipboard/clipboard_mac.h2
-rw-r--r--chromium/ui/base/clipboard/clipboard_mac.mm30
-rw-r--r--chromium/ui/base/clipboard/clipboard_metrics.cc20
-rw-r--r--chromium/ui/base/clipboard/clipboard_metrics.h30
-rw-r--r--chromium/ui/base/clipboard/clipboard_non_backed.cc (renamed from chromium/ui/base/clipboard/clipboard_aura.cc)208
-rw-r--r--chromium/ui/base/clipboard/clipboard_non_backed.h (renamed from chromium/ui/base/clipboard/clipboard_aura.h)24
-rw-r--r--chromium/ui/base/clipboard/clipboard_ozone.cc22
-rw-r--r--chromium/ui/base/clipboard/clipboard_test_template.h80
-rw-r--r--chromium/ui/base/clipboard/clipboard_util_mac.mm1
-rw-r--r--chromium/ui/base/clipboard/clipboard_win.cc9
-rw-r--r--chromium/ui/base/clipboard/clipboard_x11.cc337
-rw-r--r--chromium/ui/base/clipboard/scoped_clipboard_writer.cc16
-rw-r--r--chromium/ui/base/clipboard/scoped_clipboard_writer.h5
20 files changed, 570 insertions, 359 deletions
diff --git a/chromium/ui/base/clipboard/BUILD.gn b/chromium/ui/base/clipboard/BUILD.gn
index 61570cc1f2e..b36512c4c36 100644
--- a/chromium/ui/base/clipboard/BUILD.gn
+++ b/chromium/ui/base/clipboard/BUILD.gn
@@ -20,29 +20,30 @@ jumbo_component("clipboard_types") {
"clipboard_constants.h",
]
+ if (!is_ios) {
+ sources += [ "clipboard_format_type.h" ]
+ }
+
if (is_android) {
sources += [ "clipboard_format_type_android.cc" ]
}
if (is_mac) {
- sources += [
- "clipboard_constants_mac.mm",
- "clipboard_format_type_mac.mm",
- ]
+ sources += [ "clipboard_format_type_mac.mm" ]
+ }
+
+ if (is_mac || is_ios) {
+ sources += [ "clipboard_constants_mac.mm" ]
}
if (is_win) {
sources += [ "clipboard_format_type_win.cc" ]
}
- if (!is_ios) {
- if (use_aura) {
- if ((use_x11 && is_desktop_linux) || !is_win) {
- sources += [ "clipboard_format_type_aura.cc" ]
- }
+ if (use_aura) {
+ if ((use_x11 && is_desktop_linux) || !is_win) {
+ sources += [ "clipboard_format_type_aura.cc" ]
}
-
- sources += [ "clipboard_format_type.h" ]
}
defines = [ "IS_UI_BASE_CLIPBOARD_TYPES_IMPL" ]
@@ -50,11 +51,11 @@ jumbo_component("clipboard_types") {
deps = [ "//base" ]
libs = []
+ if (is_mac || is_ios) {
+ libs += [ "Foundation.framework" ]
+ }
if (is_mac) {
- libs += [
- "AppKit.framework",
- "CoreFoundation.framework",
- ]
+ libs += [ "AppKit.framework" ]
}
}
@@ -64,6 +65,8 @@ jumbo_component("clipboard") {
sources = [
"clipboard.cc",
"clipboard.h",
+ "clipboard_metrics.cc",
+ "clipboard_metrics.h",
"clipboard_monitor.cc",
"clipboard_monitor.h",
"clipboard_observer.h",
@@ -112,16 +115,17 @@ jumbo_component("clipboard") {
public_deps = [ ":clipboard_types" ]
if (use_aura) {
- # Aura clipboard.
- # Chromecast uses clipboard_aura now.
+ # Linux clipboard implementations.
if (is_desktop_linux && !is_chromecast) {
+ sources += [ "clipboard_linux.cc" ]
if (use_ozone) {
sources += [
"clipboard_ozone.cc",
"clipboard_ozone.h",
]
deps += [ "//ui/base" ]
- } else if (use_x11) {
+ }
+ if (use_x11) {
sources += [
"clipboard_x11.cc",
"clipboard_x11.h",
@@ -136,20 +140,20 @@ jumbo_component("clipboard") {
]
}
} else if (is_chromeos && ozone_platform_x11) {
- # linux-chromeos uses aura clipboard by default, but supports ozone x11
- # with flag --use-system-clipbboard.
+ # linux-chromeos uses non-backed clipboard by default, but supports ozone
+ # x11 with flag --use-system-clipbboard.
sources += [
- "clipboard_aura.cc",
- "clipboard_aura.h",
+ "clipboard_non_backed.cc",
+ "clipboard_non_backed.h",
"clipboard_ozone.cc",
"clipboard_ozone.h",
]
deps += [ "//ui/base" ]
} else if (!is_win) {
- # This file is used for all non-X11, non-Windows aura Builds.
+ # This file is used for all builds not backed by an underlying platform.
sources += [
- "clipboard_aura.cc",
- "clipboard_aura.h",
+ "clipboard_non_backed.cc",
+ "clipboard_non_backed.h",
]
}
}
@@ -181,10 +185,10 @@ jumbo_source_set("clipboard_test_support") {
"test/test_clipboard.cc",
"test/test_clipboard.h",
]
+ }
- if (is_android) {
- sources += [ "clipboard_android_test_support.cc" ]
- }
+ if (is_android) {
+ sources += [ "clipboard_android_test_support.cc" ]
}
public_deps = [
@@ -206,17 +210,17 @@ source_set("clipboard_test") {
sources = []
output_name = "ui_base_clipboard_test"
- if (is_mac) {
+ if (!is_ios) {
sources += [
- "clipboard_mac_unittest.mm",
- "clipboard_util_mac_unittest.mm",
+ "custom_data_helper_unittest.cc",
+ "test/test_clipboard_unittest.cc",
]
}
- if (!is_ios) {
+ if (is_mac) {
sources += [
- "custom_data_helper_unittest.cc",
- "test/test_clipboard_unittest.cc",
+ "clipboard_mac_unittest.mm",
+ "clipboard_util_mac_unittest.mm",
]
}
diff --git a/chromium/ui/base/clipboard/clipboard.cc b/chromium/ui/base/clipboard/clipboard.cc
index a91de7c9517..a7722e261c1 100644
--- a/chromium/ui/base/clipboard/clipboard.cc
+++ b/chromium/ui/base/clipboard/clipboard.cc
@@ -203,4 +203,10 @@ base::Lock& Clipboard::ClipboardMapLock() {
return *clipboard_map_lock;
}
+bool Clipboard::IsMarkedByOriginatorAsConfidential() const {
+ return false;
+}
+
+void Clipboard::MarkAsConfidential() {}
+
} // namespace ui
diff --git a/chromium/ui/base/clipboard/clipboard.h b/chromium/ui/base/clipboard/clipboard.h
index 40f0e4d5e0d..1a69e8420d8 100644
--- a/chromium/ui/base/clipboard/clipboard.h
+++ b/chromium/ui/base/clipboard/clipboard.h
@@ -110,6 +110,17 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard
virtual bool IsFormatAvailable(const ClipboardFormatType& format,
ClipboardBuffer buffer) const = 0;
+ // Returns whether the clipboard has data that is marked by its originator as
+ // confidential. This is available for opt-in checking by the user of this API
+ // as confidential information, like passwords, might legitimately need to be
+ // manipulated.
+ virtual bool IsMarkedByOriginatorAsConfidential() const;
+
+ // Mark the data on the clipboard as being confidential. This isn't
+ // implemented for all platforms yet, but this call should be made on every
+ // platform so that when it is implemented on other platforms it is picked up.
+ virtual void MarkAsConfidential();
+
// Clear the clipboard data.
virtual void Clear(ClipboardBuffer buffer) = 0;
diff --git a/chromium/ui/base/clipboard/clipboard_android.cc b/chromium/ui/base/clipboard/clipboard_android.cc
index 501d191e961..917d0d9d135 100644
--- a/chromium/ui/base/clipboard/clipboard_android.cc
+++ b/chromium/ui/base/clipboard/clipboard_android.cc
@@ -21,10 +21,12 @@
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.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"
@@ -149,9 +151,8 @@ std::string ClipboardMap::Get(const std::string& format) {
}
void ClipboardMap::GetImage(ReadImageCallback callback) {
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING},
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
base::BindOnce(&GetImageData, clipboard_manager_), std::move(callback));
}
@@ -432,6 +433,7 @@ void ClipboardAndroid::ReadAsciiText(ClipboardBuffer buffer,
std::string* result) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kText);
*result = g_map.Get().Get(ClipboardFormatType::GetPlainTextType().GetName());
}
@@ -443,6 +445,7 @@ void ClipboardAndroid::ReadHTML(ClipboardBuffer buffer,
uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kHtml);
if (src_url)
src_url->clear();
@@ -464,6 +467,7 @@ void ClipboardAndroid::ReadImage(ClipboardBuffer buffer,
ReadImageCallback callback) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kImage);
g_map.Get().GetImage(std::move(callback));
}
@@ -483,6 +487,7 @@ void ClipboardAndroid::ReadBookmark(base::string16* title,
void ClipboardAndroid::ReadData(const ClipboardFormatType& format,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kData);
*result = g_map.Get().Get(format.GetName());
}
diff --git a/chromium/ui/base/clipboard/clipboard_constants.h b/chromium/ui/base/clipboard/clipboard_constants.h
index 52048077f19..f57524d56b6 100644
--- a/chromium/ui/base/clipboard/clipboard_constants.h
+++ b/chromium/ui/base/clipboard/clipboard_constants.h
@@ -44,13 +44,20 @@ extern const char kMimeTypePepperCustomData[];
// Pickled data.
COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
extern NSString* const kWebCustomDataPboardType;
+
// Tells us if WebKit was the last to write to the pasteboard. There's no
// actual data associated with this type.
COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
extern NSString* const kWebSmartPastePboardType;
+
// Pepper custom data format type.
COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
extern NSString* const kPepperCustomDataPboardType;
+
+// Data format used to tag the current data as confidential.
+COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
+extern NSString* const kUTTypeConfidentialData;
+
#endif // defined(OS_MACOSX)
#if defined(OS_ANDROID)
diff --git a/chromium/ui/base/clipboard/clipboard_constants_mac.mm b/chromium/ui/base/clipboard/clipboard_constants_mac.mm
index 4f3029f6200..8633a201234 100644
--- a/chromium/ui/base/clipboard/clipboard_constants_mac.mm
+++ b/chromium/ui/base/clipboard/clipboard_constants_mac.mm
@@ -14,4 +14,9 @@ NSString* const kWebSmartPastePboardType = @"NeXT smart paste pasteboard type";
NSString* const kPepperCustomDataPboardType =
@"org.chromium.pepper-custom-data";
+// It is the common convention on the Mac and on iOS that password managers tag
+// confidential data with the flavor "org.nspasteboard.ConcealedType". Obey this
+// convention. See http://nspasteboard.org/ for more info.
+NSString* const kUTTypeConfidentialData = @"org.nspasteboard.ConcealedType";
+
} // namespace ui
diff --git a/chromium/ui/base/clipboard/clipboard_linux.cc b/chromium/ui/base/clipboard/clipboard_linux.cc
new file mode 100644
index 00000000000..ef42052ed5d
--- /dev/null
+++ b/chromium/ui/base/clipboard/clipboard_linux.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.h"
+
+#if defined(USE_OZONE)
+#include "ui/base/clipboard/clipboard_ozone.h"
+#include "ui/base/ui_base_features.h"
+#endif
+
+#if defined(USE_X11)
+#include "ui/base/clipboard/clipboard_x11.h"
+#endif
+
+namespace ui {
+
+// Clipboard factory method.
+Clipboard* Clipboard::Create() {
+#if defined(USE_OZONE)
+ if (features::IsUsingOzonePlatform())
+ return new ClipboardOzone();
+#endif
+
+#if defined(USE_X11)
+ return new ClipboardX11();
+#else
+ NOTREACHED();
+ return nullptr;
+#endif
+}
+
+} // namespace ui
diff --git a/chromium/ui/base/clipboard/clipboard_mac.h b/chromium/ui/base/clipboard/clipboard_mac.h
index 9ebd21cd157..507a7f8c786 100644
--- a/chromium/ui/base/clipboard/clipboard_mac.h
+++ b/chromium/ui/base/clipboard/clipboard_mac.h
@@ -33,6 +33,8 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardMac : public Clipboard {
uint64_t GetSequenceNumber(ClipboardBuffer buffer) const override;
bool IsFormatAvailable(const ClipboardFormatType& format,
ClipboardBuffer buffer) const override;
+ bool IsMarkedByOriginatorAsConfidential() const override;
+ void MarkAsConfidential() override;
void Clear(ClipboardBuffer buffer) override;
void ReadAvailableTypes(ClipboardBuffer buffer,
std::vector<base::string16>* types) const override;
diff --git a/chromium/ui/base/clipboard/clipboard_mac.mm b/chromium/ui/base/clipboard/clipboard_mac.mm
index 4c8e0e874b0..c396f9effea 100644
--- a/chromium/ui/base/clipboard/clipboard_mac.mm
+++ b/chromium/ui/base/clipboard/clipboard_mac.mm
@@ -24,6 +24,7 @@
#import "third_party/mozilla/NSPasteboard+Utils.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/base/clipboard/clipboard_util_mac.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/canvas.h"
@@ -85,6 +86,27 @@ bool ClipboardMac::IsFormatAvailable(const ClipboardFormatType& format,
return [types containsObject:format.ToNSString()];
}
+bool ClipboardMac::IsMarkedByOriginatorAsConfidential() const {
+ DCHECK(CalledOnValidThread());
+
+ NSPasteboard* pb = GetPasteboard();
+ NSPasteboardType type =
+ [pb availableTypeFromArray:@[ kUTTypeConfidentialData ]];
+
+ if (type)
+ return true;
+
+ return false;
+}
+
+void ClipboardMac::MarkAsConfidential() {
+ DCHECK(CalledOnValidThread());
+
+ NSPasteboard* pb = GetPasteboard();
+ [pb addTypes:@[ kUTTypeConfidentialData ] owner:nil];
+ [pb setData:nil forType:kUTTypeConfidentialData];
+}
+
void ClipboardMac::Clear(ClipboardBuffer buffer) {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
@@ -138,6 +160,7 @@ void ClipboardMac::ReadText(ClipboardBuffer buffer,
base::string16* result) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kText);
NSPasteboard* pb = GetPasteboard();
NSString* contents = [pb stringForType:NSPasteboardTypeString];
@@ -148,6 +171,7 @@ void ClipboardMac::ReadAsciiText(ClipboardBuffer buffer,
std::string* result) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kText);
NSPasteboard* pb = GetPasteboard();
NSString* contents = [pb stringForType:NSPasteboardTypeString];
@@ -164,6 +188,7 @@ void ClipboardMac::ReadHTML(ClipboardBuffer buffer,
uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kHtml);
// TODO(avi): src_url?
markup->clear();
@@ -191,12 +216,14 @@ void ClipboardMac::ReadHTML(ClipboardBuffer buffer,
void ClipboardMac::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kRtf);
return ReadData(ClipboardFormatType::GetRtfType(), result);
}
void ClipboardMac::ReadImage(ClipboardBuffer buffer,
ReadImageCallback callback) const {
+ RecordRead(ClipboardFormatMetric::kImage);
std::move(callback).Run(ReadImageInternal(buffer, GetPasteboard()));
}
@@ -205,6 +232,7 @@ void ClipboardMac::ReadCustomData(ClipboardBuffer buffer,
base::string16* result) const {
DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kCustomData);
NSPasteboard* pb = GetPasteboard();
if ([[pb types] containsObject:kWebCustomDataPboardType]) {
@@ -216,6 +244,7 @@ void ClipboardMac::ReadCustomData(ClipboardBuffer buffer,
void ClipboardMac::ReadBookmark(base::string16* title, std::string* url) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kBookmark);
NSPasteboard* pb = GetPasteboard();
if (title) {
@@ -235,6 +264,7 @@ void ClipboardMac::ReadBookmark(base::string16* title, std::string* url) const {
void ClipboardMac::ReadData(const ClipboardFormatType& format,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kData);
NSPasteboard* pb = GetPasteboard();
NSData* data = [pb dataForType:format.ToNSString()];
if ([data length])
diff --git a/chromium/ui/base/clipboard/clipboard_metrics.cc b/chromium/ui/base/clipboard/clipboard_metrics.cc
new file mode 100644
index 00000000000..dc52ad67926
--- /dev/null
+++ b/chromium/ui/base/clipboard/clipboard_metrics.cc
@@ -0,0 +1,20 @@
+// 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_metrics.h"
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+
+namespace ui {
+
+void RecordRead(ClipboardFormatMetric metric) {
+ base::UmaHistogramEnumeration("Clipboard.Read", metric);
+}
+
+void RecordWrite(ClipboardFormatMetric metric) {
+ base::UmaHistogramEnumeration("Clipboard.Write", metric);
+}
+
+} // namespace ui
diff --git a/chromium/ui/base/clipboard/clipboard_metrics.h b/chromium/ui/base/clipboard/clipboard_metrics.h
new file mode 100644
index 00000000000..5077043bafe
--- /dev/null
+++ b/chromium/ui/base/clipboard/clipboard_metrics.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_METRICS_H_
+#define UI_BASE_CLIPBOARD_CLIPBOARD_METRICS_H_
+
+namespace ui {
+
+// Used to log formats read/written from/to the platform clipboard.
+//
+// This enum's values are persisted to logs. Do not reuse or renumber values.
+enum class ClipboardFormatMetric {
+ kText = 0, // On applicable platforms, includes both UNICODE and ANSI text.
+ kHtml = 1,
+ kRtf = 2,
+ kImage = 3,
+ kBookmark = 4,
+ kData = 5,
+ kCustomData = 6,
+ kWebSmartPaste = 7, // Only used on write.
+ kMaxValue = kWebSmartPaste,
+};
+
+void RecordRead(ClipboardFormatMetric metric);
+void RecordWrite(ClipboardFormatMetric metric);
+
+} // namespace ui
+
+#endif // UI_BASE_CLIPBOARD_CLIPBOARD_MONITOR_H_
diff --git a/chromium/ui/base/clipboard/clipboard_aura.cc b/chromium/ui/base/clipboard/clipboard_non_backed.cc
index 9f4ae70a5ed..2b827891f6d 100644
--- a/chromium/ui/base/clipboard/clipboard_aura.cc
+++ b/chromium/ui/base/clipboard/clipboard_non_backed.cc
@@ -2,7 +2,7 @@
// 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_aura.h"
+#include "ui/base/clipboard/clipboard_non_backed.h"
#include <stdint.h>
@@ -22,6 +22,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/clipboard_format_type.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/geometry/size.h"
@@ -33,8 +34,8 @@ namespace {
const size_t kMaxClipboardSize = 1;
-// Clipboard data format used by AuraClipboard.
-enum class AuraClipboardFormat {
+// Clipboard data format used by ClipboardInternal.
+enum class ClipboardInternalFormat {
kText = 1 << 0,
kHtml = 1 << 1,
kRtf = 1 << 2,
@@ -48,49 +49,47 @@ enum class AuraClipboardFormat {
// It mostly just provides APIs to cleanly access and manipulate this data.
class ClipboardData {
public:
- ClipboardData()
- : web_smart_paste_(false),
- format_(0) {}
+ ClipboardData() : web_smart_paste_(false), format_(0) {}
virtual ~ClipboardData() = default;
- // Bitmask of AuraClipboardFormat types.
+ // Bitmask of ClipboardInternalFormat types.
int format() const { return format_; }
const std::string& text() const { return text_; }
void set_text(const std::string& text) {
text_ = text;
- format_ |= static_cast<int>(AuraClipboardFormat::kText);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kText);
}
const std::string& markup_data() const { return markup_data_; }
void set_markup_data(const std::string& markup_data) {
markup_data_ = markup_data;
- format_ |= static_cast<int>(AuraClipboardFormat::kHtml);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kHtml);
}
const std::string& rtf_data() const { return rtf_data_; }
void SetRTFData(const std::string& rtf_data) {
rtf_data_ = rtf_data;
- format_ |= static_cast<int>(AuraClipboardFormat::kRtf);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kRtf);
}
const std::string& url() const { return url_; }
void set_url(const std::string& url) {
url_ = url;
- format_ |= static_cast<int>(AuraClipboardFormat::kHtml);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kHtml);
}
const std::string& bookmark_title() const { return bookmark_title_; }
void set_bookmark_title(const std::string& bookmark_title) {
bookmark_title_ = bookmark_title;
- format_ |= static_cast<int>(AuraClipboardFormat::kBookmark);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kBookmark);
}
const std::string& bookmark_url() const { return bookmark_url_; }
void set_bookmark_url(const std::string& bookmark_url) {
bookmark_url_ = bookmark_url;
- format_ |= static_cast<int>(AuraClipboardFormat::kBookmark);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kBookmark);
}
const SkBitmap& bitmap() const { return bitmap_; }
@@ -99,7 +98,7 @@ class ClipboardData {
NOTREACHED() << "Unable to convert bitmap for clipboard";
return;
}
- format_ |= static_cast<int>(AuraClipboardFormat::kBitmap);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kBitmap);
}
const std::string& custom_data_format() const { return custom_data_format_; }
@@ -113,13 +112,13 @@ class ClipboardData {
}
custom_data_data_ = data_data;
custom_data_format_ = data_format;
- format_ |= static_cast<int>(AuraClipboardFormat::kCustom);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kCustom);
}
bool web_smart_paste() const { return web_smart_paste_; }
void set_web_smart_paste(bool web_smart_paste) {
web_smart_paste_ = web_smart_paste;
- format_ |= static_cast<int>(AuraClipboardFormat::kWeb);
+ format_ |= static_cast<int>(ClipboardInternalFormat::kWeb);
}
private:
@@ -157,16 +156,13 @@ class ClipboardData {
} // namespace
-// Platform clipboard implementation for Aura. This handles things like format
-// conversion, versioning of clipboard items etc. The goal is to roughly provide
-// a substitute to platform clipboards on other platforms such as GtkClipboard
-// on gtk or winapi clipboard on win.
-class AuraClipboard {
+// Simple, internal implementation of a clipboard, handling things like format
+// conversion, versioning, etc.
+class ClipboardInternal {
public:
- AuraClipboard() : sequence_number_(0) {
- }
+ ClipboardInternal() : sequence_number_(0) {}
- ~AuraClipboard() = default;
+ ~ClipboardInternal() = default;
void Clear() {
sequence_number_++;
@@ -174,9 +170,7 @@ class AuraClipboard {
ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
}
- uint64_t sequence_number() const {
- return sequence_number_;
- }
+ uint64_t sequence_number() const { return sequence_number_; }
// Returns the data currently on the top of the clipboard stack, nullptr if
// the clipboard stack is empty.
@@ -188,11 +182,11 @@ class AuraClipboard {
// Returns true if the data on top of the clipboard stack has format |format|
// or another format that can be converted to |format|.
- bool IsFormatAvailable(AuraClipboardFormat format) const {
+ bool IsFormatAvailable(ClipboardInternalFormat format) const {
switch (format) {
- case AuraClipboardFormat::kText:
- return HasFormat(AuraClipboardFormat::kText) ||
- HasFormat(AuraClipboardFormat::kBookmark);
+ case ClipboardInternalFormat::kText:
+ return HasFormat(ClipboardInternalFormat::kText) ||
+ HasFormat(ClipboardInternalFormat::kBookmark);
default:
return HasFormat(format);
}
@@ -211,11 +205,11 @@ class AuraClipboard {
const ClipboardData* data = GetData();
if (!data)
return;
- if (HasFormat(AuraClipboardFormat::kText))
+ if (HasFormat(ClipboardInternalFormat::kText))
*result = data->text();
- else if (HasFormat(AuraClipboardFormat::kHtml))
+ else if (HasFormat(ClipboardInternalFormat::kHtml))
*result = data->markup_data();
- else if (HasFormat(AuraClipboardFormat::kBookmark))
+ else if (HasFormat(ClipboardInternalFormat::kBookmark))
*result = data->bookmark_url();
}
@@ -230,7 +224,7 @@ class AuraClipboard {
*fragment_start = 0;
*fragment_end = 0;
- if (!HasFormat(AuraClipboardFormat::kHtml))
+ if (!HasFormat(ClipboardInternalFormat::kHtml))
return;
const ClipboardData* data = GetData();
@@ -246,7 +240,7 @@ class AuraClipboard {
void ReadRTF(std::string* result) const {
result->clear();
const ClipboardData* data = GetData();
- if (!HasFormat(AuraClipboardFormat::kRtf))
+ if (!HasFormat(ClipboardInternalFormat::kRtf))
return;
*result = data->rtf_data();
@@ -255,7 +249,7 @@ class AuraClipboard {
// Reads image from the data at the top of clipboard stack.
SkBitmap ReadImage() const {
SkBitmap img;
- if (!HasFormat(AuraClipboardFormat::kBitmap))
+ if (!HasFormat(ClipboardInternalFormat::kBitmap))
return img;
// A shallow copy should be fine here, but just to be safe...
@@ -272,7 +266,7 @@ class AuraClipboard {
base::string16* result) const {
result->clear();
const ClipboardData* data = GetData();
- if (!HasFormat(AuraClipboardFormat::kCustom))
+ if (!HasFormat(ClipboardInternalFormat::kCustom))
return;
ReadCustomDataForType(data->custom_data_data().c_str(),
@@ -285,7 +279,7 @@ class AuraClipboard {
title->clear();
if (url)
url->clear();
- if (!HasFormat(AuraClipboardFormat::kBookmark))
+ if (!HasFormat(ClipboardInternalFormat::kBookmark))
return;
const ClipboardData* data = GetData();
@@ -298,7 +292,7 @@ class AuraClipboard {
void ReadData(const std::string& type, std::string* result) const {
result->clear();
const ClipboardData* data = GetData();
- if (!HasFormat(AuraClipboardFormat::kCustom) ||
+ if (!HasFormat(ClipboardInternalFormat::kCustom) ||
type != data->custom_data_format())
return;
@@ -314,7 +308,7 @@ class AuraClipboard {
private:
// True if the data on top of the clipboard stack has format |format|.
- bool HasFormat(AuraClipboardFormat format) const {
+ bool HasFormat(ClipboardInternalFormat format) const {
const ClipboardData* data = GetData();
return data ? data->format() & static_cast<int>(format) : false;
}
@@ -337,13 +331,13 @@ class AuraClipboard {
// Sequence number uniquely identifying clipboard state.
uint64_t sequence_number_;
- DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
+ DISALLOW_COPY_AND_ASSIGN(ClipboardInternal);
};
// Helper class to build a ClipboardData object and write it to clipboard.
class ClipboardDataBuilder {
public:
- static void CommitToClipboard(AuraClipboard* clipboard) {
+ static void CommitToClipboard(ClipboardInternal* clipboard) {
clipboard->WriteData(TakeCurrentData());
}
@@ -411,58 +405,63 @@ class ClipboardDataBuilder {
ClipboardData* ClipboardDataBuilder::current_data_ = nullptr;
-// linux-chromeos uses aura clipboard by default, but supports ozone x11
+// linux-chromeos uses non-backed clipboard by default, but supports ozone x11
// with flag --use-system-clipbboard.
#if !defined(OS_CHROMEOS) || !BUILDFLAG(OZONE_PLATFORM_X11)
// Clipboard factory method.
Clipboard* Clipboard::Create() {
- return new ClipboardAura;
+ return new ClipboardNonBacked;
}
#endif
-// ClipboardAura implementation.
-ClipboardAura::ClipboardAura()
- : clipboard_internal_(std::make_unique<AuraClipboard>()) {
+// ClipboardNonBacked implementation.
+ClipboardNonBacked::ClipboardNonBacked()
+ : clipboard_internal_(std::make_unique<ClipboardInternal>()) {
DCHECK(CalledOnValidThread());
}
-ClipboardAura::~ClipboardAura() {
+ClipboardNonBacked::~ClipboardNonBacked() {
DCHECK(CalledOnValidThread());
}
-void ClipboardAura::OnPreShutdown() {}
+void ClipboardNonBacked::OnPreShutdown() {}
-uint64_t ClipboardAura::GetSequenceNumber(ClipboardBuffer buffer) const {
+uint64_t ClipboardNonBacked::GetSequenceNumber(ClipboardBuffer buffer) const {
DCHECK(CalledOnValidThread());
return clipboard_internal_->sequence_number();
}
-bool ClipboardAura::IsFormatAvailable(const ClipboardFormatType& format,
- ClipboardBuffer buffer) const {
+bool ClipboardNonBacked::IsFormatAvailable(const ClipboardFormatType& format,
+ ClipboardBuffer buffer) const {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(buffer));
if (ClipboardFormatType::GetPlainTextType().Equals(format) ||
ClipboardFormatType::GetUrlType().Equals(format))
- return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kText);
+ return clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kText);
if (ClipboardFormatType::GetHtmlType().Equals(format))
- return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kHtml);
+ return clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kHtml);
if (ClipboardFormatType::GetRtfType().Equals(format))
- return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kRtf);
+ return clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kRtf);
if (ClipboardFormatType::GetBitmapType().Equals(format))
- return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kBitmap);
+ return clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kBitmap);
if (ClipboardFormatType::GetWebKitSmartPasteType().Equals(format))
- return clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kWeb);
+ return clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kWeb);
const ClipboardData* data = clipboard_internal_->GetData();
return data && data->custom_data_format() == format.GetName();
}
-void ClipboardAura::Clear(ClipboardBuffer buffer) {
+void ClipboardNonBacked::Clear(ClipboardBuffer buffer) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(buffer));
clipboard_internal_->Clear();
}
-void ClipboardAura::ReadAvailableTypes(
+void ClipboardNonBacked::ReadAvailableTypes(
ClipboardBuffer buffer,
std::vector<base::string16>* types) const {
DCHECK(CalledOnValidThread());
@@ -481,7 +480,8 @@ void ClipboardAura::ReadAvailableTypes(
if (IsFormatAvailable(ClipboardFormatType::GetBitmapType(), buffer))
types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
- if (clipboard_internal_->IsFormatAvailable(AuraClipboardFormat::kCustom) &&
+ if (clipboard_internal_->IsFormatAvailable(
+ ClipboardInternalFormat::kCustom) &&
clipboard_internal_->GetData()) {
ReadCustomDataTypes(
clipboard_internal_->GetData()->custom_data_data().c_str(),
@@ -490,7 +490,7 @@ void ClipboardAura::ReadAvailableTypes(
}
std::vector<base::string16>
-ClipboardAura::ReadAvailablePlatformSpecificFormatNames(
+ClipboardNonBacked::ReadAvailablePlatformSpecificFormatNames(
ClipboardBuffer buffer) const {
DCHECK(CalledOnValidThread());
@@ -516,59 +516,69 @@ ClipboardAura::ReadAvailablePlatformSpecificFormatNames(
return types;
}
-void ClipboardAura::ReadText(ClipboardBuffer buffer,
- base::string16* result) const {
+void ClipboardNonBacked::ReadText(ClipboardBuffer buffer,
+ base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
clipboard_internal_->ReadText(result);
}
-void ClipboardAura::ReadAsciiText(ClipboardBuffer buffer,
- std::string* result) const {
+void ClipboardNonBacked::ReadAsciiText(ClipboardBuffer buffer,
+ std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
clipboard_internal_->ReadAsciiText(result);
}
-void ClipboardAura::ReadHTML(ClipboardBuffer buffer,
- base::string16* markup,
- std::string* src_url,
- uint32_t* fragment_start,
- uint32_t* fragment_end) const {
+void ClipboardNonBacked::ReadHTML(ClipboardBuffer buffer,
+ base::string16* markup,
+ std::string* src_url,
+ uint32_t* fragment_start,
+ uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kHtml);
clipboard_internal_->ReadHTML(markup, src_url, fragment_start, fragment_end);
}
-void ClipboardAura::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
+void ClipboardNonBacked::ReadRTF(ClipboardBuffer buffer,
+ std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kRtf);
clipboard_internal_->ReadRTF(result);
}
-void ClipboardAura::ReadImage(ClipboardBuffer buffer,
- ReadImageCallback callback) const {
+void ClipboardNonBacked::ReadImage(ClipboardBuffer buffer,
+ ReadImageCallback callback) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kImage);
std::move(callback).Run(clipboard_internal_->ReadImage());
}
-void ClipboardAura::ReadCustomData(ClipboardBuffer buffer,
- const base::string16& type,
- base::string16* result) const {
+void ClipboardNonBacked::ReadCustomData(ClipboardBuffer buffer,
+ const base::string16& type,
+ base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kCustomData);
clipboard_internal_->ReadCustomData(type, result);
}
-void ClipboardAura::ReadBookmark(base::string16* title,
- std::string* url) const {
+void ClipboardNonBacked::ReadBookmark(base::string16* title,
+ std::string* url) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kBookmark);
clipboard_internal_->ReadBookmark(title, url);
}
-void ClipboardAura::ReadData(const ClipboardFormatType& format,
- std::string* result) const {
+void ClipboardNonBacked::ReadData(const ClipboardFormatType& format,
+ std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kData);
clipboard_internal_->ReadData(format.GetName(), result);
}
-void ClipboardAura::WritePortableRepresentations(ClipboardBuffer buffer,
- const ObjectMap& objects) {
+void ClipboardNonBacked::WritePortableRepresentations(
+ ClipboardBuffer buffer,
+ const ObjectMap& objects) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(buffer));
for (const auto& object : objects)
@@ -576,7 +586,7 @@ void ClipboardAura::WritePortableRepresentations(ClipboardBuffer buffer,
ClipboardDataBuilder::CommitToClipboard(clipboard_internal_.get());
}
-void ClipboardAura::WritePlatformRepresentations(
+void ClipboardNonBacked::WritePlatformRepresentations(
ClipboardBuffer buffer,
std::vector<Clipboard::PlatformRepresentation> platform_representations) {
DCHECK(CalledOnValidThread());
@@ -587,39 +597,39 @@ void ClipboardAura::WritePlatformRepresentations(
ClipboardDataBuilder::CommitToClipboard(clipboard_internal_.get());
}
-void ClipboardAura::WriteText(const char* text_data, size_t text_len) {
+void ClipboardNonBacked::WriteText(const char* text_data, size_t text_len) {
ClipboardDataBuilder::WriteText(text_data, text_len);
}
-void ClipboardAura::WriteHTML(const char* markup_data,
- size_t markup_len,
- const char* url_data,
- size_t url_len) {
+void ClipboardNonBacked::WriteHTML(const char* markup_data,
+ size_t markup_len,
+ const char* url_data,
+ size_t url_len) {
ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len);
}
-void ClipboardAura::WriteRTF(const char* rtf_data, size_t data_len) {
+void ClipboardNonBacked::WriteRTF(const char* rtf_data, size_t data_len) {
ClipboardDataBuilder::WriteRTF(rtf_data, data_len);
}
-void ClipboardAura::WriteBookmark(const char* title_data,
- size_t title_len,
- const char* url_data,
- size_t url_len) {
+void ClipboardNonBacked::WriteBookmark(const char* title_data,
+ size_t title_len,
+ const char* url_data,
+ size_t url_len) {
ClipboardDataBuilder::WriteBookmark(title_data, title_len, url_data, url_len);
}
-void ClipboardAura::WriteWebSmartPaste() {
+void ClipboardNonBacked::WriteWebSmartPaste() {
ClipboardDataBuilder::WriteWebSmartPaste();
}
-void ClipboardAura::WriteBitmap(const SkBitmap& bitmap) {
+void ClipboardNonBacked::WriteBitmap(const SkBitmap& bitmap) {
ClipboardDataBuilder::WriteBitmap(bitmap);
}
-void ClipboardAura::WriteData(const ClipboardFormatType& format,
- const char* data_data,
- size_t data_len) {
+void ClipboardNonBacked::WriteData(const ClipboardFormatType& format,
+ const char* data_data,
+ size_t data_len) {
ClipboardDataBuilder::WriteData(format.GetName(), data_data, data_len);
}
diff --git a/chromium/ui/base/clipboard/clipboard_aura.h b/chromium/ui/base/clipboard/clipboard_non_backed.h
index 6a6862ba688..8f57aca1e25 100644
--- a/chromium/ui/base/clipboard/clipboard_aura.h
+++ b/chromium/ui/base/clipboard/clipboard_non_backed.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_AURA_H_
-#define UI_BASE_CLIPBOARD_CLIPBOARD_AURA_H_
+#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_NON_BACKED_H_
+#define UI_BASE_CLIPBOARD_CLIPBOARD_NON_BACKED_H_
#include <stddef.h>
#include <stdint.h>
@@ -13,13 +13,19 @@
namespace ui {
-class AuraClipboard;
+class ClipboardInternal;
-class ClipboardAura : public Clipboard {
+// In-memory clipboard implementation not backed by an underlying platform.
+// This clipboard can be used where there's no need to sync the clipboard with
+// an underlying platform, and can substitute platform clipboards like
+// ClipboardWin on Windows or ClipboardMac on MacOS. As this isn't backed by an
+// underlying platform, the clipboard data isn't persisted after an instance
+// goes away.
+class ClipboardNonBacked : public Clipboard {
private:
friend class Clipboard;
- ClipboardAura();
- ~ClipboardAura() override;
+ ClipboardNonBacked();
+ ~ClipboardNonBacked() override;
// Clipboard overrides:
void OnPreShutdown() override;
@@ -70,11 +76,11 @@ class ClipboardAura : public Clipboard {
const char* data_data,
size_t data_len) override;
- const std::unique_ptr<AuraClipboard> clipboard_internal_;
+ const std::unique_ptr<ClipboardInternal> clipboard_internal_;
- DISALLOW_COPY_AND_ASSIGN(ClipboardAura);
+ DISALLOW_COPY_AND_ASSIGN(ClipboardNonBacked);
};
} // namespace ui
-#endif // UI_BASE_CLIPBOARD_CLIPBOARD_AURA_H_
+#endif // UI_BASE_CLIPBOARD_CLIPBOARD_NON_BACKED_H_
diff --git a/chromium/ui/base/clipboard/clipboard_ozone.cc b/chromium/ui/base/clipboard/clipboard_ozone.cc
index bb5b7ad7182..a41bc2f5798 100644
--- a/chromium/ui/base/clipboard/clipboard_ozone.cc
+++ b/chromium/ui/base/clipboard/clipboard_ozone.cc
@@ -15,9 +15,11 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/codec/png_codec.h"
@@ -27,7 +29,7 @@
#if defined(OS_CHROMEOS) && BUILDFLAG(OZONE_PLATFORM_X11)
#include "base/command_line.h"
-#include "ui/base/clipboard/clipboard_aura.h"
+#include "ui/base/clipboard/clipboard_non_backed.h"
#include "ui/base/ui_base_switches.h"
#endif
@@ -294,18 +296,21 @@ class ClipboardOzone::AsyncClipboardOzone {
DISALLOW_COPY_AND_ASSIGN(AsyncClipboardOzone);
};
+// Uses the factory in the clipboard_linux otherwise.
+#if defined(OS_CHROMEOS) || !defined(OS_LINUX)
// Clipboard factory method.
Clipboard* Clipboard::Create() {
-// linux-chromeos uses aura clipboard by default, but supports ozone x11
+// linux-chromeos uses non-backed clipboard by default, but supports ozone x11
// with flag --use-system-clipbboard.
#if defined(OS_CHROMEOS) && BUILDFLAG(OZONE_PLATFORM_X11)
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseSystemClipboard)) {
- return new ClipboardAura;
+ return new ClipboardNonBacked;
}
#endif
return new ClipboardOzone;
}
+#endif
// ClipboardOzone implementation.
ClipboardOzone::ClipboardOzone() {
@@ -383,6 +388,7 @@ ClipboardOzone::ReadAvailablePlatformSpecificFormatNames(
void ClipboardOzone::ReadText(ClipboardBuffer buffer,
base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
auto clipboard_data =
async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeText);
@@ -393,6 +399,7 @@ void ClipboardOzone::ReadText(ClipboardBuffer buffer,
void ClipboardOzone::ReadAsciiText(ClipboardBuffer buffer,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
auto clipboard_data =
async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeText);
@@ -405,6 +412,7 @@ void ClipboardOzone::ReadHTML(ClipboardBuffer buffer,
uint32_t* fragment_start,
uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kHtml);
markup->clear();
if (src_url)
@@ -423,6 +431,7 @@ void ClipboardOzone::ReadHTML(ClipboardBuffer buffer,
void ClipboardOzone::ReadRTF(ClipboardBuffer buffer,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kRtf);
auto clipboard_data =
async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeRTF);
@@ -431,6 +440,7 @@ void ClipboardOzone::ReadRTF(ClipboardBuffer buffer,
void ClipboardOzone::ReadImage(ClipboardBuffer buffer,
ReadImageCallback callback) const {
+ RecordRead(ClipboardFormatMetric::kImage);
std::move(callback).Run(ReadImageInternal(buffer));
}
@@ -438,6 +448,7 @@ void ClipboardOzone::ReadCustomData(ClipboardBuffer buffer,
const base::string16& type,
base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kCustomData);
auto custom_data = async_clipboard_ozone_->ReadClipboardDataAndWait(
buffer, kMimeTypeWebCustomData);
@@ -454,6 +465,7 @@ void ClipboardOzone::ReadBookmark(base::string16* title,
void ClipboardOzone::ReadData(const ClipboardFormatType& format,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kData);
auto clipboard_data = async_clipboard_ozone_->ReadClipboardDataAndWait(
ClipboardBuffer::kCopyPaste, format.GetName());
@@ -469,8 +481,8 @@ void ClipboardOzone::WritePortableRepresentations(ClipboardBuffer buffer,
async_clipboard_ozone_->OfferData(buffer);
- // Just like Aura/X11 implementation does, copy text data from the copy/paste
- // selection to the primary selection.
+ // Just like Non-Backed/X11 implementation does, copy text data from the
+ // copy/paste selection to the primary selection.
if (buffer == ClipboardBuffer::kCopyPaste) {
auto text_iter = objects.find(PortableFormat::kText);
if (text_iter != objects.end()) {
diff --git a/chromium/ui/base/clipboard/clipboard_test_template.h b/chromium/ui/base/clipboard/clipboard_test_template.h
index f31c2594b7d..279252ce350 100644
--- a/chromium/ui/base/clipboard/clipboard_test_template.h
+++ b/chromium/ui/base/clipboard/clipboard_test_template.h
@@ -46,6 +46,7 @@
#endif
#if defined(USE_X11)
+#include "ui/base/ui_base_features.h"
#include "ui/events/platform/platform_event_source.h"
#endif
@@ -67,7 +68,8 @@ class ClipboardTest : public PlatformTest {
void SetUp() override {
PlatformTest::SetUp();
#if defined(USE_X11)
- event_source_ = ClipboardTraits::GetEventSource();
+ if (!features::IsUsingOzonePlatform())
+ event_source_ = ClipboardTraits::GetEventSource();
#endif
clipboard_ = ClipboardTraits::Create();
}
@@ -653,8 +655,8 @@ TYPED_TEST(ClipboardTest, DataTest) {
}
// TODO(https://crbug.com/1032161): Implement multiple raw types for
-// AuraClipboard. This test currently doesn't run on AuraClipboard because
-// AuraClipboard only supports one raw type.
+// ClipboardInternal. This test currently doesn't run on ClipboardInternal
+// because ClipboardInternal only supports one raw type.
#if (!defined(USE_AURA) || defined(OS_WIN) || defined(USE_OZONE) || \
defined(USE_X11)) && \
!defined(OS_CHROMEOS)
@@ -739,17 +741,38 @@ TYPED_TEST(ClipboardTest, ReadAvailablePlatformSpecificFormatNamesTest) {
#endif
}
-// Test that a platform-specific write works.
+// Test that platform-specific functionality works, with a predefined format in
+// On X11 Linux, this test uses a simple MIME type, text/plain.
+// On Windows, this test uses a pre-defined ANSI format, CF_TEXT, and tests that
+// the Windows implicitly converts this to UNICODE as expected.
+#if defined(OS_WIN) || defined(USE_X11)
+TYPED_TEST(ClipboardTest, PlatformSpecificDataTest) {
+ // We're testing platform-specific behavior, so use PlatformClipboardTest.
+ // TODO(https://crbug.com/1083050): The template shouldn't know about its
+ // instantiations. Move this information up using a flag, virtual method, or
+ // creating separate test files for different platforms.
+ std::string test_suite_name = ::testing::UnitTest::GetInstance()
+ ->current_test_info()
+ ->test_suite_name();
+ if (test_suite_name != std::string("ClipboardTest/PlatformClipboardTest"))
+ return;
+
+ const std::string text = "test string";
#if defined(OS_WIN)
-TYPED_TEST(ClipboardTest, WindowsPredefinedFormatWriteDataTest) {
+ // Windows pre-defined ANSI text format.
const std::string kFormatString = "CF_TEXT";
- const std::string text = "test string";
+ // Windows requires an extra '\0' at the end for a raw write.
+ const std::string kPlatformSpecificText = text + '\0';
+#elif defined(USE_X11)
+ const std::string kFormatString = "text/plain"; // X11 text format
+ const std::string kPlatformSpecificText = text;
+#endif
base::span<const uint8_t> text_span(
- reinterpret_cast<const uint8_t*>(text.data()), text.size() + 1);
-
+ reinterpret_cast<const uint8_t*>(kPlatformSpecificText.data()),
+ kPlatformSpecificText.size());
{
ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste);
- clipboard_writer.WriteData(UTF8ToUTF16(kFormatString),
+ clipboard_writer.WriteData(ASCIIToUTF16(kFormatString),
mojo_base::BigBuffer(text_span));
}
@@ -758,27 +781,32 @@ TYPED_TEST(ClipboardTest, WindowsPredefinedFormatWriteDataTest) {
ClipboardBuffer::kCopyPaste);
EXPECT_THAT(raw_types, Contains(ASCIIToUTF16(kFormatString)));
+
+#if defined(OS_WIN)
+ // Only Windows ClipboardFormatType recognizes ANSI formats.
EXPECT_TRUE(this->clipboard().IsFormatAvailable(
ClipboardFormatType::GetPlainTextAType(), ClipboardBuffer::kCopyPaste));
+#endif // defined(OS_WIN)
- // Only ClipboardWin recognizes the Windows-specific CF_TEXT.
- std::string test_suite_name = ::testing::UnitTest::GetInstance()
- ->current_test_info()
- ->test_suite_name();
- if (test_suite_name == std::string("ClipboardTest/PlatformClipboardTest")) {
- std::string text_result;
- this->clipboard().ReadAsciiText(ClipboardBuffer::kCopyPaste, &text_result);
- EXPECT_EQ(text, text_result);
-
- // Windows will automatically convert CF_TEXT to its UNICODE version.
- EXPECT_TRUE(this->clipboard().IsFormatAvailable(
- ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste));
- base::string16 text_result16;
- this->clipboard().ReadText(ClipboardBuffer::kCopyPaste, &text_result16);
- EXPECT_EQ(base::ASCIIToUTF16(text), text_result16);
- }
+ EXPECT_TRUE(this->clipboard().IsFormatAvailable(
+ ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste));
+
+ std::string text_result;
+ this->clipboard().ReadAsciiText(ClipboardBuffer::kCopyPaste, &text_result);
+ EXPECT_EQ(text_result, text);
+ // Note: Windows will automatically convert CF_TEXT to its UNICODE version.
+ EXPECT_TRUE(this->clipboard().IsFormatAvailable(
+ ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste));
+ base::string16 text_result16;
+ this->clipboard().ReadText(ClipboardBuffer::kCopyPaste, &text_result16);
+ EXPECT_EQ(text_result16, base::ASCIIToUTF16(text));
+
+ std::string platform_specific_result;
+ this->clipboard().ReadData(ClipboardFormatType::GetType(kFormatString),
+ &platform_specific_result);
+ EXPECT_EQ(platform_specific_result, kPlatformSpecificText);
}
-#endif
+#endif // defined(OS_WIN) || defined(USE_X11)
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
TYPED_TEST(ClipboardTest, HyperlinkTest) {
diff --git a/chromium/ui/base/clipboard/clipboard_util_mac.mm b/chromium/ui/base/clipboard/clipboard_util_mac.mm
index a748d4af65a..8db45d20a2a 100644
--- a/chromium/ui/base/clipboard/clipboard_util_mac.mm
+++ b/chromium/ui/base/clipboard/clipboard_util_mac.mm
@@ -7,6 +7,7 @@
#include "base/mac/foundation_util.h"
#import "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/notreached.h"
namespace ui {
diff --git a/chromium/ui/base/clipboard/clipboard_win.cc b/chromium/ui/base/clipboard/clipboard_win.cc
index 9bfabd34eab..421f22eaaf6 100644
--- a/chromium/ui/base/clipboard/clipboard_win.cc
+++ b/chromium/ui/base/clipboard/clipboard_win.cc
@@ -30,6 +30,7 @@
#include "skia/ext/skia_utils_win.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/base/clipboard/clipboard_util_win.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/canvas.h"
@@ -319,6 +320,7 @@ ClipboardWin::ReadAvailablePlatformSpecificFormatNames(
void ClipboardWin::ReadText(ClipboardBuffer buffer,
base::string16* result) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kText);
if (!result) {
NOTREACHED();
return;
@@ -344,6 +346,7 @@ void ClipboardWin::ReadText(ClipboardBuffer buffer,
void ClipboardWin::ReadAsciiText(ClipboardBuffer buffer,
std::string* result) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kText);
if (!result) {
NOTREACHED();
return;
@@ -372,6 +375,7 @@ void ClipboardWin::ReadHTML(ClipboardBuffer buffer,
uint32_t* fragment_start,
uint32_t* fragment_end) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kHtml);
markup->clear();
// TODO(dcheng): Remove these checks, I don't think they should be optional.
@@ -425,6 +429,7 @@ void ClipboardWin::ReadHTML(ClipboardBuffer buffer,
void ClipboardWin::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kRtf);
ReadData(ClipboardFormatType::GetRtfType(), result);
TrimAfterNull(result);
@@ -432,6 +437,7 @@ void ClipboardWin::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
void ClipboardWin::ReadImage(ClipboardBuffer buffer,
ReadImageCallback callback) const {
+ RecordRead(ClipboardFormatMetric::kImage);
std::move(callback).Run(ReadImageInternal(buffer));
}
@@ -439,6 +445,7 @@ void ClipboardWin::ReadCustomData(ClipboardBuffer buffer,
const base::string16& type,
base::string16* result) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+ RecordRead(ClipboardFormatMetric::kCustomData);
// Acquire the clipboard.
ScopedClipboard clipboard;
@@ -455,6 +462,7 @@ void ClipboardWin::ReadCustomData(ClipboardBuffer buffer,
}
void ClipboardWin::ReadBookmark(base::string16* title, std::string* url) const {
+ RecordRead(ClipboardFormatMetric::kBookmark);
if (title)
title->clear();
@@ -481,6 +489,7 @@ void ClipboardWin::ReadBookmark(base::string16* title, std::string* url) const {
void ClipboardWin::ReadData(const ClipboardFormatType& format,
std::string* result) const {
+ RecordRead(ClipboardFormatMetric::kData);
if (!result) {
NOTREACHED();
return;
diff --git a/chromium/ui/base/clipboard/clipboard_x11.cc b/chromium/ui/base/clipboard/clipboard_x11.cc
index 95e2caff21a..c2f3620584b 100644
--- a/chromium/ui/base/clipboard/clipboard_x11.cc
+++ b/chromium/ui/base/clipboard/clipboard_x11.cc
@@ -22,8 +22,10 @@
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/clipboard/custom_data_helper.h"
+#include "ui/base/nine_image_painter_factory.h"
#include "ui/base/x/selection_owner.h"
#include "ui/base/x/selection_requestor.h"
#include "ui/base/x/selection_utils.h"
@@ -32,8 +34,12 @@
#include "ui/events/x/x11_window_event_manager.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/x/connection.h"
+#include "ui/gfx/x/event.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
+#include "ui/gfx/x/xfixes.h"
+#include "ui/gfx/x/xproto.h"
namespace ui {
@@ -61,63 +67,57 @@ class SelectionChangeObserver : public XEventObserver {
~SelectionChangeObserver() override;
// XEventObserver:
- void WillProcessXEvent(XEvent* xev) override;
- void DidProcessXEvent(XEvent* xev) override {}
+ void WillProcessXEvent(x11::Event* xev) override;
+ void DidProcessXEvent(x11::Event* xev) override {}
- int event_base_;
- Atom clipboard_atom_;
- uint64_t clipboard_sequence_number_;
- uint64_t primary_sequence_number_;
+ x11::Atom clipboard_atom_{};
+ uint64_t clipboard_sequence_number_{};
+ uint64_t primary_sequence_number_{};
DISALLOW_COPY_AND_ASSIGN(SelectionChangeObserver);
};
-SelectionChangeObserver::SelectionChangeObserver()
- : event_base_(-1),
- clipboard_atom_(x11::None),
- clipboard_sequence_number_(0),
- primary_sequence_number_(0) {
- int ignored;
- if (XFixesQueryExtension(gfx::GetXDisplay(), &event_base_, &ignored)) {
- clipboard_atom_ = gfx::GetAtom(kClipboard);
- XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(),
- clipboard_atom_,
- XFixesSetSelectionOwnerNotifyMask |
- XFixesSelectionWindowDestroyNotifyMask |
- XFixesSelectionClientCloseNotifyMask);
- // This seems to be semi-optional. For some reason, registering for any
- // selection notify events seems to subscribe us to events for both the
- // primary and the clipboard buffers. Register anyway just to be safe.
- XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(),
- XA_PRIMARY,
- XFixesSetSelectionOwnerNotifyMask |
- XFixesSelectionWindowDestroyNotifyMask |
- XFixesSelectionClientCloseNotifyMask);
-
- X11EventSource::GetInstance()->AddXEventObserver(this);
- }
-}
+SelectionChangeObserver::SelectionChangeObserver() {
+ auto& xfixes = x11::Connection::Get()->xfixes();
+ // Let the server know the client version. No need to sync since we don't
+ // care what version is running on the server.
+ xfixes.QueryVersion({x11::XFixes::major_version, x11::XFixes::minor_version});
+ if (!xfixes.present())
+ return;
+
+ clipboard_atom_ = gfx::GetAtom(kClipboard);
+ auto mask = x11::XFixes::SelectionEventMask::SetSelectionOwner |
+ x11::XFixes::SelectionEventMask::SelectionWindowDestroy |
+ x11::XFixes::SelectionEventMask::SelectionClientClose;
+ xfixes.SelectSelectionInput({GetX11RootWindow(), clipboard_atom_, mask});
+ // This seems to be semi-optional. For some reason, registering for any
+ // selection notify events seems to subscribe us to events for both the
+ // primary and the clipboard buffers. Register anyway just to be safe.
+ xfixes.SelectSelectionInput({GetX11RootWindow(), x11::Atom::PRIMARY, mask});
-SelectionChangeObserver::~SelectionChangeObserver() {
- // We are a singleton; we will outlive the event source.
+ X11EventSource::GetInstance()->AddXEventObserver(this);
}
+// We are a singleton; we will outlive the event source.
+SelectionChangeObserver::~SelectionChangeObserver() = default;
+
SelectionChangeObserver* SelectionChangeObserver::GetInstance() {
return base::Singleton<SelectionChangeObserver>::get();
}
-void SelectionChangeObserver::WillProcessXEvent(XEvent* xev) {
- if (xev->type == event_base_ + XFixesSelectionNotify) {
- XFixesSelectionNotifyEvent* ev =
- reinterpret_cast<XFixesSelectionNotifyEvent*>(xev);
- if (ev->selection == clipboard_atom_) {
- clipboard_sequence_number_++;
- ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
- } else if (ev->selection == XA_PRIMARY) {
- primary_sequence_number_++;
- } else {
- DLOG(ERROR) << "Unexpected selection atom: " << ev->selection;
- }
+void SelectionChangeObserver::WillProcessXEvent(x11::Event* xev) {
+ auto* ev = xev->As<x11::XFixes::SelectionNotifyEvent>();
+ if (!ev)
+ return;
+
+ if (static_cast<x11::Atom>(ev->selection) == clipboard_atom_) {
+ clipboard_sequence_number_++;
+ ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
+ } else if (ev->selection == x11::Atom::PRIMARY) {
+ primary_sequence_number_++;
+ } else {
+ DLOG(ERROR) << "Unexpected selection atom: "
+ << static_cast<uint32_t>(ev->selection);
}
}
@@ -126,7 +126,7 @@ void SelectionChangeObserver::WillProcessXEvent(XEvent* xev) {
// Represents a list of possible return types. Copy constructable.
class TargetList {
public:
- using AtomVector = std::vector<::Atom>;
+ using AtomVector = std::vector<x11::Atom>;
explicit TargetList(const AtomVector& target_list);
@@ -134,7 +134,7 @@ class TargetList {
bool ContainsText() const;
bool ContainsFormat(const ClipboardFormatType& format_type) const;
- bool ContainsAtom(::Atom atom) const;
+ bool ContainsAtom(x11::Atom atom) const;
private:
AtomVector target_list_;
@@ -144,7 +144,7 @@ TargetList::TargetList(const AtomVector& target_list)
: target_list_(target_list) {}
bool TargetList::ContainsText() const {
- std::vector<::Atom> atoms = GetTextAtomsFrom();
+ std::vector<x11::Atom> atoms = GetTextAtomsFrom();
for (const auto& atom : atoms) {
if (ContainsAtom(atom))
return true;
@@ -154,14 +154,19 @@ bool TargetList::ContainsText() const {
}
bool TargetList::ContainsFormat(const ClipboardFormatType& format_type) const {
- ::Atom atom = gfx::GetAtom(format_type.GetName().c_str());
+ x11::Atom atom = gfx::GetAtom(format_type.GetName().c_str());
return ContainsAtom(atom);
}
-bool TargetList::ContainsAtom(::Atom atom) const {
+bool TargetList::ContainsAtom(x11::Atom atom) const {
return base::Contains(target_list_, atom);
}
+x11::Window GetSelectionOwner(x11::Atom selection) {
+ auto response = x11::Connection::Get()->GetSelectionOwner({selection}).Sync();
+ return response ? response->owner : x11::Window::None;
+}
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
@@ -176,14 +181,14 @@ class ClipboardX11::X11Details : public XEventDispatcher {
// Returns the X11 selection atom that we pass to various XSelection functions
// for the given buffer.
- ::Atom LookupSelectionForClipboardBuffer(ClipboardBuffer buffer) const;
+ x11::Atom LookupSelectionForClipboardBuffer(ClipboardBuffer buffer) const;
// Returns the X11 selection atom that we pass to various XSelection functions
// for ClipboardBuffer::kCopyPaste.
- ::Atom GetCopyPasteSelection() const;
+ x11::Atom GetCopyPasteSelection() const;
// Finds the SelectionFormatMap for the incoming selection atom.
- const SelectionFormatMap& LookupStorageForAtom(::Atom atom);
+ const SelectionFormatMap& LookupStorageForAtom(x11::Atom atom);
// As we need to collect all the data types before we tell X11 that we own a
// particular selection, we create a temporary clipboard mapping that
@@ -208,7 +213,7 @@ class ClipboardX11::X11Details : public XEventDispatcher {
// and do the asynchronous dance with whatever application is holding the
// selection.
SelectionData RequestAndWaitForTypes(ClipboardBuffer buffer,
- const std::vector<::Atom>& types);
+ const std::vector<x11::Atom>& types);
// Retrieves the list of possible data types the current clipboard owner has.
//
@@ -217,10 +222,10 @@ class ClipboardX11::X11Details : public XEventDispatcher {
TargetList WaitAndGetTargetsList(ClipboardBuffer buffer);
// Returns a list of all text atoms that we handle.
- std::vector<::Atom> GetTextAtoms() const;
+ std::vector<x11::Atom> GetTextAtoms() const;
// Returns a vector with a |format| converted to an X11 atom.
- std::vector<::Atom> GetAtomsForFormat(const ClipboardFormatType& format);
+ std::vector<x11::Atom> GetAtomsForFormat(const ClipboardFormatType& format);
// Clears a certain clipboard buffer, whether we own it or not.
void Clear(ClipboardBuffer buffer);
@@ -231,16 +236,14 @@ class ClipboardX11::X11Details : public XEventDispatcher {
private:
// XEventDispatcher:
- bool DispatchXEvent(XEvent* xev) override;
-
- bool CanDispatchXEvent(XEvent* xev);
+ bool DispatchXEvent(x11::Event* xev) override;
// Our X11 state.
- Display* x_display_;
- ::Window x_root_window_;
+ x11::Connection* connection_;
+ x11::Window x_root_window_;
// Input-only window used as a selection owner.
- ::Window x_window_;
+ x11::Window x_window_;
// Events selected on |x_window_|.
std::unique_ptr<XScopedEventSelector> x_window_events_;
@@ -259,26 +262,16 @@ class ClipboardX11::X11Details : public XEventDispatcher {
};
ClipboardX11::X11Details::X11Details()
- : x_display_(gfx::GetXDisplay()),
- x_root_window_(DefaultRootWindow(x_display_)),
- x_window_(XCreateWindow(x_display_,
- x_root_window_,
- -100,
- -100,
- 10,
- 10, // x, y, width, height
- 0, // border width
- CopyFromParent, // depth
- InputOnly,
- CopyFromParent, // visual
- 0,
- nullptr)),
- selection_requestor_(x_display_, x_window_, this),
- clipboard_owner_(x_display_, x_window_, gfx::GetAtom(kClipboard)),
- primary_owner_(x_display_, x_window_, XA_PRIMARY) {
- XStoreName(x_display_, x_window_, "Chromium clipboard");
- x_window_events_.reset(
- new XScopedEventSelector(x_window_, PropertyChangeMask));
+ : connection_(x11::Connection::Get()),
+ x_root_window_(ui::GetX11RootWindow()),
+ x_window_(CreateDummyWindow("Chromium Clipboard Window")),
+ selection_requestor_(x_window_, this),
+ clipboard_owner_(connection_, x_window_, gfx::GetAtom(kClipboard)),
+ 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);
if (X11EventSource::GetInstance())
X11EventSource::GetInstance()->AddXEventDispatcher(this);
@@ -288,24 +281,24 @@ ClipboardX11::X11Details::~X11Details() {
if (X11EventSource::GetInstance())
X11EventSource::GetInstance()->RemoveXEventDispatcher(this);
- XDestroyWindow(x_display_, x_window_);
+ connection_->DestroyWindow({x_window_});
}
-::Atom ClipboardX11::X11Details::LookupSelectionForClipboardBuffer(
+x11::Atom ClipboardX11::X11Details::LookupSelectionForClipboardBuffer(
ClipboardBuffer buffer) const {
if (buffer == ClipboardBuffer::kCopyPaste)
return GetCopyPasteSelection();
- return XA_PRIMARY;
+ return x11::Atom::PRIMARY;
}
-::Atom ClipboardX11::X11Details::GetCopyPasteSelection() const {
+x11::Atom ClipboardX11::X11Details::GetCopyPasteSelection() const {
return gfx::GetAtom(kClipboard);
}
const SelectionFormatMap& ClipboardX11::X11Details::LookupStorageForAtom(
- ::Atom atom) {
- if (atom == XA_PRIMARY)
+ x11::Atom atom) {
+ if (atom == x11::Atom::PRIMARY)
return primary_owner_.selection_format_map();
DCHECK_EQ(GetCopyPasteSelection(), atom);
@@ -319,7 +312,7 @@ void ClipboardX11::X11Details::CreateNewClipboardData() {
void ClipboardX11::X11Details::InsertMapping(
const std::string& key,
const scoped_refptr<base::RefCountedMemory>& memory) {
- ::Atom atom_key = gfx::GetAtom(key.c_str());
+ x11::Atom atom_key = gfx::GetAtom(key.c_str());
clipboard_data_.Insert(atom_key, memory);
}
@@ -333,9 +326,9 @@ void ClipboardX11::X11Details::TakeOwnershipOfSelection(
SelectionData ClipboardX11::X11Details::RequestAndWaitForTypes(
ClipboardBuffer buffer,
- const std::vector<::Atom>& types) {
- ::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
- if (XGetSelectionOwner(x_display_, selection_name) == x_window_) {
+ const std::vector<x11::Atom>& types) {
+ x11::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
+ if (GetSelectionOwner(selection_name) == x_window_) {
// We can local fastpath instead of playing the nested run loop game
// with the X server.
const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
@@ -348,8 +341,8 @@ SelectionData ClipboardX11::X11Details::RequestAndWaitForTypes(
} else {
TargetList targets = WaitAndGetTargetsList(buffer);
- ::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
- std::vector<::Atom> intersection;
+ x11::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
+ std::vector<x11::Atom> intersection;
GetAtomIntersection(types, targets.target_list(), &intersection);
return selection_requestor_.RequestAndWaitForTypes(selection_name,
intersection);
@@ -360,27 +353,25 @@ SelectionData ClipboardX11::X11Details::RequestAndWaitForTypes(
TargetList ClipboardX11::X11Details::WaitAndGetTargetsList(
ClipboardBuffer buffer) {
- ::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
- std::vector<::Atom> out;
- if (XGetSelectionOwner(x_display_, selection_name) == x_window_) {
+ x11::Atom selection_name = LookupSelectionForClipboardBuffer(buffer);
+ std::vector<x11::Atom> out;
+ if (GetSelectionOwner(selection_name) == x_window_) {
// We can local fastpath and return the list of local targets.
const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
for (const auto& format : format_map)
out.push_back(format.first);
} else {
- scoped_refptr<base::RefCountedMemory> data;
- size_t out_data_items = 0;
- ::Atom out_type = x11::None;
+ std::vector<uint8_t> data;
+ x11::Atom out_type = x11::Atom::None;
if (selection_requestor_.PerformBlockingConvertSelection(
- selection_name, gfx::GetAtom(kTargets), &data, &out_data_items,
- &out_type)) {
+ selection_name, gfx::GetAtom(kTargets), &data, &out_type)) {
// Some apps return an |out_type| of "TARGETS". (crbug.com/377893)
- if (out_type == XA_ATOM || out_type == gfx::GetAtom(kTargets)) {
- const ::Atom* atom_array =
- reinterpret_cast<const ::Atom*>(data->front());
- for (size_t i = 0; i < out_data_items; ++i)
+ if (out_type == x11::Atom::ATOM || out_type == gfx::GetAtom(kTargets)) {
+ const x11::Atom* atom_array =
+ reinterpret_cast<const x11::Atom*>(data.data());
+ for (size_t i = 0; i < data.size() / sizeof(x11::Atom); ++i)
out.push_back(atom_array[i]);
}
} else {
@@ -390,11 +381,11 @@ TargetList ClipboardX11::X11Details::WaitAndGetTargetsList(
// text. This is pretty unfortunate since it means we have to actually
// copy the data to see if it is available, but at least this path
// shouldn't be hit for conforming programs.
- std::vector<::Atom> types = GetTextAtoms();
+ std::vector<x11::Atom> types = GetTextAtoms();
for (const auto& text_atom : types) {
- ::Atom type = x11::None;
+ x11::Atom type = x11::Atom::None;
if (selection_requestor_.PerformBlockingConvertSelection(
- selection_name, text_atom, nullptr, nullptr, &type) &&
+ selection_name, text_atom, nullptr, &type) &&
type == text_atom) {
out.push_back(text_atom);
}
@@ -405,11 +396,11 @@ TargetList ClipboardX11::X11Details::WaitAndGetTargetsList(
return TargetList(out);
}
-std::vector<::Atom> ClipboardX11::X11Details::GetTextAtoms() const {
+std::vector<x11::Atom> ClipboardX11::X11Details::GetTextAtoms() const {
return GetTextAtomsFrom();
}
-std::vector<::Atom> ClipboardX11::X11Details::GetAtomsForFormat(
+std::vector<x11::Atom> ClipboardX11::X11Details::GetAtomsForFormat(
const ClipboardFormatType& format) {
return {gfx::GetAtom(format.GetName().c_str())};
}
@@ -422,18 +413,18 @@ void ClipboardX11::X11Details::Clear(ClipboardBuffer buffer) {
}
void ClipboardX11::X11Details::StoreCopyPasteDataAndWait() {
- ::Atom selection = GetCopyPasteSelection();
- if (XGetSelectionOwner(x_display_, selection) != x_window_)
+ x11::Atom selection = GetCopyPasteSelection();
+ if (GetSelectionOwner(selection) != x_window_)
return;
- ::Atom clipboard_manager_atom = gfx::GetAtom(kClipboardManager);
- if (XGetSelectionOwner(x_display_, clipboard_manager_atom) == x11::None)
+ x11::Atom clipboard_manager_atom = gfx::GetAtom(kClipboardManager);
+ if (GetSelectionOwner(clipboard_manager_atom) == x11::Window::None)
return;
const SelectionFormatMap& format_map = LookupStorageForAtom(selection);
if (format_map.size() == 0)
return;
- std::vector<Atom> targets = format_map.GetTypes();
+ std::vector<x11::Atom> targets = format_map.GetTypes();
base::TimeTicks start = base::TimeTicks::Now();
selection_requestor_.PerformBlockingConvertSelectionWithParameter(
@@ -442,71 +433,45 @@ void ClipboardX11::X11Details::StoreCopyPasteDataAndWait() {
base::TimeTicks::Now() - start);
}
-bool ClipboardX11::X11Details::CanDispatchXEvent(XEvent* xev) {
- if (xev->xany.window == x_window_)
- return true;
-
- if (xev->type == PropertyNotify) {
- return primary_owner_.CanDispatchPropertyEvent(*xev) ||
- clipboard_owner_.CanDispatchPropertyEvent(*xev) ||
- selection_requestor_.CanDispatchPropertyEvent(*xev);
- }
- return false;
-}
-
-bool ClipboardX11::X11Details::DispatchXEvent(XEvent* xev) {
- if (!CanDispatchXEvent(xev))
- return false;
-
- switch (xev->type) {
- case SelectionRequest: {
- if (xev->xselectionrequest.selection == XA_PRIMARY) {
- primary_owner_.OnSelectionRequest(*xev);
- } else {
- // We should not get requests for the CLIPBOARD_MANAGER selection
- // because we never take ownership of it.
- DCHECK_EQ(GetCopyPasteSelection(), xev->xselectionrequest.selection);
- clipboard_owner_.OnSelectionRequest(*xev);
- }
- break;
- }
- case SelectionNotify: {
- selection_requestor_.OnSelectionNotify(*xev);
- break;
- }
- case SelectionClear: {
- if (xev->xselectionclear.selection == XA_PRIMARY) {
- primary_owner_.OnSelectionClear(*xev);
- } else {
- // We should not get requests for the CLIPBOARD_MANAGER selection
- // because we never take ownership of it.
- DCHECK_EQ(GetCopyPasteSelection(), xev->xselection.selection);
- clipboard_owner_.OnSelectionClear(*xev);
- }
- break;
+bool ClipboardX11::X11Details::DispatchXEvent(x11::Event* xev) {
+ if (auto* request = xev->As<x11::SelectionRequestEvent>()) {
+ if (request->owner != x_window_)
+ return false;
+ if (request->selection == x11::Atom::PRIMARY) {
+ primary_owner_.OnSelectionRequest(*xev);
+ } else {
+ // We should not get requests for the CLIPBOARD_MANAGER selection
+ // because we never take ownership of it.
+ DCHECK_EQ(GetCopyPasteSelection(), request->selection);
+ clipboard_owner_.OnSelectionRequest(*xev);
}
- case PropertyNotify: {
- if (primary_owner_.CanDispatchPropertyEvent(*xev))
- primary_owner_.OnPropertyEvent(*xev);
- if (clipboard_owner_.CanDispatchPropertyEvent(*xev))
- clipboard_owner_.OnPropertyEvent(*xev);
- if (selection_requestor_.CanDispatchPropertyEvent(*xev))
- selection_requestor_.OnPropertyEvent(*xev);
- break;
+ } else if (auto* notify = xev->As<x11::SelectionNotifyEvent>()) {
+ if (notify->requestor != x_window_)
+ return false;
+ selection_requestor_.OnSelectionNotify(*notify);
+ } else if (auto* clear = xev->As<x11::SelectionClearEvent>()) {
+ if (clear->owner != x_window_)
+ return false;
+ if (clear->selection == x11::Atom::PRIMARY) {
+ primary_owner_.OnSelectionClear(*xev);
+ } else {
+ // We should not get requests for the CLIPBOARD_MANAGER selection
+ // because we never take ownership of it.
+ DCHECK_EQ(GetCopyPasteSelection(), clear->selection);
+ clipboard_owner_.OnSelectionClear(*xev);
}
- default:
- break;
+ } else if (auto* prop = xev->As<x11::PropertyNotifyEvent>()) {
+ if (primary_owner_.CanDispatchPropertyEvent(*xev))
+ primary_owner_.OnPropertyEvent(*xev);
+ if (clipboard_owner_.CanDispatchPropertyEvent(*xev))
+ clipboard_owner_.OnPropertyEvent(*xev);
+ if (selection_requestor_.CanDispatchPropertyEvent(*xev))
+ selection_requestor_.OnPropertyEvent(*xev);
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
-// Clipboard factory method.
-Clipboard* Clipboard::Create() {
- return new ClipboardX11;
-}
-
-///////////////////////////////////////////////////////////////////////////////
// ClipboardX11
ClipboardX11::ClipboardX11() : x11_details_(new X11Details) {
@@ -586,17 +551,16 @@ ClipboardX11::ReadAvailablePlatformSpecificFormatNames(
if (target_list.empty())
return {};
- std::vector<char*> types_buffer(target_list.size());
- // Call XGetAtomNames to minimize trips to the X11 server.
- int status = XGetAtomNames(gfx::GetXDisplay(), target_list.data(),
- target_list.size(), types_buffer.data());
- DCHECK(status) << "XGetAtomNames failed! An invalid Atom was passed in.";
-
+ std::vector<x11::Future<x11::GetAtomNameReply>> futures;
+ for (x11::Atom target : target_list)
+ futures.push_back(x11::Connection::Get()->GetAtomName({target}));
std::vector<base::string16> types;
types.reserve(target_list.size());
- for (char* type : types_buffer) {
- types.push_back(base::UTF8ToUTF16(type));
- XFree(type);
+ for (auto& future : futures) {
+ if (auto response = future.Sync())
+ types.push_back(base::UTF8ToUTF16(response->name));
+ else
+ types.emplace_back();
}
return types;
@@ -605,6 +569,7 @@ ClipboardX11::ReadAvailablePlatformSpecificFormatNames(
void ClipboardX11::ReadText(ClipboardBuffer buffer,
base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
SelectionData data(x11_details_->RequestAndWaitForTypes(
buffer, x11_details_->GetTextAtoms()));
@@ -617,6 +582,7 @@ void ClipboardX11::ReadText(ClipboardBuffer buffer,
void ClipboardX11::ReadAsciiText(ClipboardBuffer buffer,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kText);
SelectionData data(x11_details_->RequestAndWaitForTypes(
buffer, x11_details_->GetTextAtoms()));
@@ -632,6 +598,7 @@ void ClipboardX11::ReadHTML(ClipboardBuffer buffer,
uint32_t* fragment_start,
uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kHtml);
markup->clear();
if (src_url)
src_url->clear();
@@ -652,6 +619,7 @@ void ClipboardX11::ReadHTML(ClipboardBuffer buffer,
void ClipboardX11::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kRtf);
SelectionData data(x11_details_->RequestAndWaitForTypes(
buffer,
@@ -663,6 +631,7 @@ void ClipboardX11::ReadRTF(ClipboardBuffer buffer, std::string* result) const {
void ClipboardX11::ReadImage(ClipboardBuffer buffer,
ReadImageCallback callback) const {
DCHECK(IsSupportedClipboardBuffer(buffer));
+ RecordRead(ClipboardFormatMetric::kImage);
std::move(callback).Run(ReadImageInternal(buffer));
}
@@ -670,6 +639,7 @@ void ClipboardX11::ReadCustomData(ClipboardBuffer buffer,
const base::string16& type,
base::string16* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kCustomData);
SelectionData data(x11_details_->RequestAndWaitForTypes(
buffer, x11_details_->GetAtomsForFormat(
@@ -687,6 +657,7 @@ void ClipboardX11::ReadBookmark(base::string16* title, std::string* url) const {
void ClipboardX11::ReadData(const ClipboardFormatType& format,
std::string* result) const {
DCHECK(CalledOnValidThread());
+ RecordRead(ClipboardFormatMetric::kData);
SelectionData data(x11_details_->RequestAndWaitForTypes(
ClipboardBuffer::kCopyPaste, x11_details_->GetAtomsForFormat(format)));
diff --git a/chromium/ui/base/clipboard/scoped_clipboard_writer.cc b/chromium/ui/base/clipboard/scoped_clipboard_writer.cc
index 1b8312f5fc5..c723b0d2e33 100644
--- a/chromium/ui/base/clipboard/scoped_clipboard_writer.cc
+++ b/chromium/ui/base/clipboard/scoped_clipboard_writer.cc
@@ -8,6 +8,7 @@
#include "base/strings/utf_string_conversions.h"
#include "net/base/escape.h"
#include "ui/base/clipboard/clipboard_format_type.h"
+#include "ui/base/clipboard/clipboard_metrics.h"
#include "ui/gfx/geometry/size.h"
// Documentation on the format of the parameters for each clipboard target can
@@ -31,9 +32,12 @@ ScopedClipboardWriter::~ScopedClipboardWriter() {
Clipboard::GetForCurrentThread()->WritePlatformRepresentations(
buffer_, std::move(platform_representations_));
}
+ if (confidential_)
+ Clipboard::GetForCurrentThread()->MarkAsConfidential();
}
void ScopedClipboardWriter::WriteText(const base::string16& text) {
+ RecordWrite(ClipboardFormatMetric::kText);
std::string utf8_text = base::UTF16ToUTF8(text);
Clipboard::ObjectMapParams parameters;
@@ -44,6 +48,7 @@ void ScopedClipboardWriter::WriteText(const base::string16& text) {
void ScopedClipboardWriter::WriteHTML(const base::string16& markup,
const std::string& source_url) {
+ RecordWrite(ClipboardFormatMetric::kHtml);
std::string utf8_markup = base::UTF16ToUTF8(markup);
Clipboard::ObjectMapParams parameters;
@@ -59,6 +64,7 @@ void ScopedClipboardWriter::WriteHTML(const base::string16& markup,
}
void ScopedClipboardWriter::WriteRTF(const std::string& rtf_data) {
+ RecordWrite(ClipboardFormatMetric::kRtf);
Clipboard::ObjectMapParams parameters;
parameters.push_back(Clipboard::ObjectMapParam(rtf_data.begin(),
rtf_data.end()));
@@ -69,6 +75,7 @@ void ScopedClipboardWriter::WriteBookmark(const base::string16& bookmark_title,
const std::string& url) {
if (bookmark_title.empty() || url.empty())
return;
+ RecordWrite(ClipboardFormatMetric::kBookmark);
std::string utf8_markup = base::UTF16ToUTF8(bookmark_title);
@@ -94,6 +101,7 @@ void ScopedClipboardWriter::WriteHyperlink(const base::string16& anchor_text,
}
void ScopedClipboardWriter::WriteWebSmartPaste() {
+ RecordWrite(ClipboardFormatMetric::kWebSmartPaste);
objects_[Clipboard::PortableFormat::kWebkit] = Clipboard::ObjectMapParams();
}
@@ -101,6 +109,7 @@ void ScopedClipboardWriter::WriteImage(const SkBitmap& bitmap) {
if (bitmap.drawsNothing())
return;
DCHECK(bitmap.getPixels());
+ RecordWrite(ClipboardFormatMetric::kImage);
bitmap_ = bitmap;
// TODO(dcheng): This is slightly less horrible than what we used to do, but
@@ -114,9 +123,14 @@ void ScopedClipboardWriter::WriteImage(const SkBitmap& bitmap) {
objects_[Clipboard::PortableFormat::kBitmap] = parameters;
}
+void ScopedClipboardWriter::MarkAsConfidential() {
+ confidential_ = true;
+}
+
void ScopedClipboardWriter::WritePickledData(
const base::Pickle& pickle,
const ClipboardFormatType& format) {
+ RecordWrite(ClipboardFormatMetric::kCustomData);
std::string format_string = format.Serialize();
Clipboard::ObjectMapParam format_parameter(format_string.begin(),
format_string.end());
@@ -134,6 +148,7 @@ void ScopedClipboardWriter::WritePickledData(
void ScopedClipboardWriter::WriteData(const base::string16& format,
mojo_base::BigBuffer data) {
+ RecordWrite(ClipboardFormatMetric::kData);
platform_representations_.push_back(
{base::UTF16ToUTF8(format), std::move(data)});
}
@@ -142,6 +157,7 @@ void ScopedClipboardWriter::Reset() {
objects_.clear();
platform_representations_.clear();
bitmap_.reset();
+ confidential_ = false;
}
} // namespace ui
diff --git a/chromium/ui/base/clipboard/scoped_clipboard_writer.h b/chromium/ui/base/clipboard/scoped_clipboard_writer.h
index d0e5cfb3e3e..d2ed3736ce2 100644
--- a/chromium/ui/base/clipboard/scoped_clipboard_writer.h
+++ b/chromium/ui/base/clipboard/scoped_clipboard_writer.h
@@ -67,6 +67,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
void WriteImage(const SkBitmap& bitmap);
+ // Mark the data to be written as confidential.
+ void MarkAsConfidential();
+
// Removes all objects that would be written to the clipboard.
void Reset();
@@ -83,6 +86,8 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
SkBitmap bitmap_;
+ bool confidential_ = false;
+
DISALLOW_COPY_AND_ASSIGN(ScopedClipboardWriter);
};