Commit 2730a632 authored by Darwin Huang's avatar Darwin Huang Committed by Commit Bot

Android Clipboard: Make ClipboardMap keyed on ClipboardFormatType.

This allows us to avoid an unnecessary and repetitive translation layer
in ClipboardAndroid, between ClipboardFormatType and std::string.

Bug: 1123230
Change-Id: Idd749fba9bbe13c9e5e13aa0f4ea6d93d7f74b39
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2383112Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Commit-Queue: Darwin Huang <huangdarwin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807359}
parent 464b32c6
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/clipboard_data_endpoint.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/clipboard/clipboard_metrics.h"
#include "ui/base/ui_base_jni_headers/Clipboard_jni.h" #include "ui/base/ui_base_jni_headers/Clipboard_jni.h"
#include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/android/java_bitmap.h"
...@@ -88,16 +89,16 @@ class ClipboardMap { ...@@ -88,16 +89,16 @@ class ClipboardMap {
ClipboardMap(); ClipboardMap();
void SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb); void SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb);
void SetJavaSideNativePtr(Clipboard* clipboard); void SetJavaSideNativePtr(Clipboard* clipboard);
std::string Get(const std::string& format); std::string Get(const ClipboardFormatType& format);
void GetImage(ReadImageCallback callback); void GetImage(ReadImageCallback callback);
uint64_t GetSequenceNumber() const; uint64_t GetSequenceNumber() const;
base::Time GetLastModifiedTime() const; base::Time GetLastModifiedTime() const;
void ClearLastModifiedTime(); void ClearLastModifiedTime();
bool HasFormat(const std::string& format); bool HasFormat(const ClipboardFormatType& format);
std::vector<std::string> GetFormats(); std::vector<ClipboardFormatType> GetFormats();
void OnPrimaryClipboardChanged(); void OnPrimaryClipboardChanged();
void OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms); 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 CommitToAndroidClipboard();
void Clear(); void Clear();
...@@ -117,8 +118,7 @@ class ClipboardMap { ...@@ -117,8 +118,7 @@ class ClipboardMap {
// Updates |map_| and |map_state_| if necessary by fetching data from Java. // Updates |map_| and |map_state_| if necessary by fetching data from Java.
void UpdateFromAndroidClipboard(); void UpdateFromAndroidClipboard();
// TODO(huangdarwin): Refactor this to hold base::string16. std::map<ClipboardFormatType, std::string> map_ GUARDED_BY(lock_);
std::map<std::string, std::string> map_ GUARDED_BY(lock_);
MapState map_state_; MapState map_state_;
// This lock is for read/write |map_|. // This lock is for read/write |map_|.
...@@ -149,10 +149,10 @@ void ClipboardMap::SetJavaSideNativePtr(Clipboard* clipboard) { ...@@ -149,10 +149,10 @@ void ClipboardMap::SetJavaSideNativePtr(Clipboard* clipboard) {
reinterpret_cast<intptr_t>(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_); base::AutoLock lock(lock_);
UpdateFromAndroidClipboard(); 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; return it == map_.end() ? std::string() : it->second;
} }
...@@ -174,16 +174,16 @@ void ClipboardMap::ClearLastModifiedTime() { ...@@ -174,16 +174,16 @@ void ClipboardMap::ClearLastModifiedTime() {
UpdateLastModifiedTime(base::Time()); UpdateLastModifiedTime(base::Time());
} }
bool ClipboardMap::HasFormat(const std::string& format) { bool ClipboardMap::HasFormat(const ClipboardFormatType& format) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
UpdateFromAndroidClipboard(); UpdateFromAndroidClipboard();
return base::Contains(map_, format); return base::Contains(map_, format);
} }
std::vector<std::string> ClipboardMap::GetFormats() { std::vector<ClipboardFormatType> ClipboardMap::GetFormats() {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
UpdateFromAndroidClipboard(); UpdateFromAndroidClipboard();
std::vector<std::string> formats; std::vector<ClipboardFormatType> formats;
formats.reserve(map_.size()); formats.reserve(map_.size());
for (const auto& it : map_) for (const auto& it : map_)
formats.push_back(it.first); formats.push_back(it.first);
...@@ -205,7 +205,8 @@ void ClipboardMap::OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms) { ...@@ -205,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_); base::AutoLock lock(lock_);
map_[format] = data; map_[format] = data;
map_state_ = MapState::kPreparingCommit; map_state_ = MapState::kPreparingCommit;
...@@ -214,30 +215,27 @@ void ClipboardMap::Set(const std::string& format, const std::string& data) { ...@@ -214,30 +215,27 @@ void ClipboardMap::Set(const std::string& format, const std::string& data) {
void ClipboardMap::CommitToAndroidClipboard() { void ClipboardMap::CommitToAndroidClipboard() {
JNIEnv* env = AttachCurrentThread(); JNIEnv* env = AttachCurrentThread();
base::AutoLock lock(lock_); 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- // Android's API for storing HTML content on the clipboard requires a plain-
// text representation to be available as well. // text representation to be available as well.
if (!base::Contains(map_, if (!base::Contains(map_, ClipboardFormatType::GetPlainTextType()))
ClipboardFormatType::GetPlainTextType().GetName()))
return; return;
ScopedJavaLocalRef<jstring> html = ConvertUTF8ToJavaString( ScopedJavaLocalRef<jstring> html =
env, map_[ClipboardFormatType::GetHtmlType().GetName()]); ConvertUTF8ToJavaString(env, map_[ClipboardFormatType::GetHtmlType()]);
ScopedJavaLocalRef<jstring> text = ConvertUTF8ToJavaString( ScopedJavaLocalRef<jstring> text = ConvertUTF8ToJavaString(
env, map_[ClipboardFormatType::GetPlainTextType().GetName()]); env, map_[ClipboardFormatType::GetPlainTextType()]);
DCHECK(html.obj() && text.obj()); DCHECK(html.obj() && text.obj());
Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text); Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text);
} else if (base::Contains( } else if (base::Contains(map_, ClipboardFormatType::GetPlainTextType())) {
map_, ClipboardFormatType::GetPlainTextType().GetName())) {
ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString( ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(
env, map_[ClipboardFormatType::GetPlainTextType().GetName()]); env, map_[ClipboardFormatType::GetPlainTextType()]);
DCHECK(str.obj()); DCHECK(str.obj());
Java_Clipboard_setText(env, clipboard_manager_, str); Java_Clipboard_setText(env, clipboard_manager_, str);
} else if (base::Contains(map_, } else if (base::Contains(map_, ClipboardFormatType::GetBitmapType())) {
ClipboardFormatType::GetBitmapType().GetName())) { ScopedJavaLocalRef<jbyteArray> image_data =
ScopedJavaLocalRef<jbyteArray> image_data = ToJavaByteArray( ToJavaByteArray(env, map_[ClipboardFormatType::GetBitmapType()]);
env, map_[ClipboardFormatType::GetBitmapType().GetName()]);
ScopedJavaLocalRef<jstring> image_extension = ScopedJavaLocalRef<jstring> image_extension =
ConvertUTF8ToJavaString(env, kPngExtension); ConvertUTF8ToJavaString(env, kPngExtension);
DCHECK(image_data.obj()); DCHECK(image_data.obj());
...@@ -267,21 +265,22 @@ void ClipboardMap::SetLastModifiedTimeWithoutRunningCallback(base::Time time) { ...@@ -267,21 +265,22 @@ void ClipboardMap::SetLastModifiedTimeWithoutRunningCallback(base::Time time) {
last_modified_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. // entry.
void JNI_Clipboard_AddMapEntry(JNIEnv* env, void JNI_Clipboard_AddMapEntry(JNIEnv* env,
std::map<std::string, std::string>* map, std::map<ClipboardFormatType, std::string>* map,
const char* key, const ClipboardFormatType& format,
const ScopedJavaLocalRef<jstring>& jstr) { const ScopedJavaLocalRef<jstring>& jstr) {
if (jstr.is_null()) { if (jstr.is_null()) {
map->erase(key); map->erase(format);
return; return;
} }
std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); std::string str = ConvertJavaStringToUTF8(env, jstr.obj());
if (!str.empty()) { if (!str.empty()) {
(*map)[key] = str; (*map)[format] = str;
} else { } else {
map->erase(key); map->erase(format);
} }
} }
...@@ -308,12 +307,12 @@ void ClipboardMap::UpdateFromAndroidClipboard() { ...@@ -308,12 +307,12 @@ void ClipboardMap::UpdateFromAndroidClipboard() {
ScopedJavaLocalRef<jstring> jimageuri = ScopedJavaLocalRef<jstring> jimageuri =
Java_Clipboard_getImageUriString(env, clipboard_manager_); 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( JNI_Clipboard_AddMapEntry(
env, &map_, ClipboardFormatType::GetPlainTextType().GetName().c_str(), env, &map_, ClipboardFormatType::GetType(kMimeTypeImageURI), jimageuri);
jtext);
JNI_Clipboard_AddMapEntry(
env, &map_, ClipboardFormatType::GetHtmlType().GetName().c_str(), jhtml);
JNI_Clipboard_AddMapEntry(env, &map_, kMimeTypeImageURI, jimageuri);
map_state_ = MapState::kUpToDate; map_state_ = MapState::kUpToDate;
} }
...@@ -386,9 +385,10 @@ bool ClipboardAndroid::IsFormatAvailable( ...@@ -386,9 +385,10 @@ bool ClipboardAndroid::IsFormatAvailable(
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
if (format == ClipboardFormatType::GetBitmapType()) { 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) { void ClipboardAndroid::Clear(ClipboardBuffer buffer) {
...@@ -432,12 +432,12 @@ ClipboardAndroid::ReadAvailablePlatformSpecificFormatNames( ...@@ -432,12 +432,12 @@ ClipboardAndroid::ReadAvailablePlatformSpecificFormatNames(
ClipboardBuffer buffer, ClipboardBuffer buffer,
const ClipboardDataEndpoint* data_dst) const { const ClipboardDataEndpoint* data_dst) const {
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); 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; std::vector<base::string16> types;
types.reserve(formats.size()); types.reserve(formats.size());
for (const std::string& format : formats) for (const ClipboardFormatType& format : formats)
types.push_back(base::UTF8ToUTF16(format)); types.push_back(base::UTF8ToUTF16(format.GetName()));
return types; return types;
} }
...@@ -462,7 +462,7 @@ void ClipboardAndroid::ReadAsciiText(ClipboardBuffer buffer, ...@@ -462,7 +462,7 @@ void ClipboardAndroid::ReadAsciiText(ClipboardBuffer buffer,
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
RecordRead(ClipboardFormatMetric::kText); 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. // Note: |src_url| isn't really used. It is only implemented in Windows.
...@@ -480,8 +480,7 @@ void ClipboardAndroid::ReadHTML(ClipboardBuffer buffer, ...@@ -480,8 +480,7 @@ void ClipboardAndroid::ReadHTML(ClipboardBuffer buffer,
if (src_url) if (src_url)
src_url->clear(); src_url->clear();
std::string input = std::string input = g_map.Get().Get(ClipboardFormatType::GetHtmlType());
g_map.Get().Get(ClipboardFormatType::GetHtmlType().GetName());
*markup = base::UTF8ToUTF16(input); *markup = base::UTF8ToUTF16(input);
*fragment_start = 0; *fragment_start = 0;
...@@ -495,8 +494,7 @@ void ClipboardAndroid::ReadSvg(ClipboardBuffer buffer, ...@@ -495,8 +494,7 @@ void ClipboardAndroid::ReadSvg(ClipboardBuffer buffer,
base::string16* result) const { base::string16* result) const {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
std::string utf8 = std::string utf8 = g_map.Get().Get(ClipboardFormatType::GetSvgType());
g_map.Get().Get(ClipboardFormatType::GetSvgType().GetName());
*result = base::UTF8ToUTF16(utf8); *result = base::UTF8ToUTF16(utf8);
} }
...@@ -546,7 +544,7 @@ void ClipboardAndroid::ReadData(const ClipboardFormatType& format, ...@@ -546,7 +544,7 @@ void ClipboardAndroid::ReadData(const ClipboardFormatType& format,
std::string* result) const { std::string* result) const {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
RecordRead(ClipboardFormatMetric::kData); RecordRead(ClipboardFormatMetric::kData);
*result = g_map.Get().Get(format.GetName()); *result = g_map.Get().Get(format);
} }
base::Time ClipboardAndroid::GetLastModifiedTime() const { base::Time ClipboardAndroid::GetLastModifiedTime() const {
...@@ -592,7 +590,7 @@ void ClipboardAndroid::WritePlatformRepresentations( ...@@ -592,7 +590,7 @@ void ClipboardAndroid::WritePlatformRepresentations(
} }
void ClipboardAndroid::WriteText(const char* text_data, size_t text_len) { 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)); std::string(text_data, text_len));
} }
...@@ -600,12 +598,12 @@ void ClipboardAndroid::WriteHTML(const char* markup_data, ...@@ -600,12 +598,12 @@ void ClipboardAndroid::WriteHTML(const char* markup_data,
size_t markup_len, size_t markup_len,
const char* url_data, const char* url_data,
size_t url_len) { size_t url_len) {
g_map.Get().Set(ClipboardFormatType::GetHtmlType().GetName(), g_map.Get().Set(ClipboardFormatType::GetHtmlType(),
std::string(markup_data, markup_len)); std::string(markup_data, markup_len));
} }
void ClipboardAndroid::WriteSvg(const char* markup_data, size_t markup_len) { void ClipboardAndroid::WriteSvg(const char* markup_data, size_t markup_len) {
g_map.Get().Set(ClipboardFormatType::GetSvgType().GetName(), g_map.Get().Set(ClipboardFormatType::GetSvgType(),
std::string(markup_data, markup_len)); std::string(markup_data, markup_len));
} }
...@@ -619,14 +617,14 @@ void ClipboardAndroid::WriteBookmark(const char* title_data, ...@@ -619,14 +617,14 @@ void ClipboardAndroid::WriteBookmark(const char* title_data,
size_t title_len, size_t title_len,
const char* url_data, const char* url_data,
size_t url_len) { size_t url_len) {
g_map.Get().Set(ClipboardFormatType::GetUrlType().GetName(), g_map.Get().Set(ClipboardFormatType::GetUrlType(),
std::string(url_data, url_len)); std::string(url_data, url_len));
} }
// Write an extra flavor that signifies WebKit was the last to modify the // Write an extra flavor that signifies WebKit was the last to modify the
// pasteboard. This flavor has no data. // pasteboard. This flavor has no data.
void ClipboardAndroid::WriteWebSmartPaste() { void ClipboardAndroid::WriteWebSmartPaste() {
g_map.Get().Set(ClipboardFormatType::GetWebKitSmartPasteType().GetName(), g_map.Get().Set(ClipboardFormatType::GetWebKitSmartPasteType(),
std::string()); std::string());
} }
...@@ -637,13 +635,13 @@ void ClipboardAndroid::WriteBitmap(const SkBitmap& sk_bitmap) { ...@@ -637,13 +635,13 @@ void ClipboardAndroid::WriteBitmap(const SkBitmap& sk_bitmap) {
gfx::Image::CreateFrom1xBitmap(sk_bitmap).As1xPNGBytes(); gfx::Image::CreateFrom1xBitmap(sk_bitmap).As1xPNGBytes();
std::string packed(image_memory->front_as<char>(), image_memory->size()); 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, void ClipboardAndroid::WriteData(const ClipboardFormatType& format,
const char* data_data, const char* data_data,
size_t data_len) { 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 } // namespace ui
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment