Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/base/clipboard/clipboard.h" | 5 #include "ui/base/clipboard/clipboard.h" |
| 6 | 6 |
| 7 #include "base/android/jni_string.h" | 7 #include "base/android/jni_string.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 } | 121 } |
| 122 | 122 |
| 123 void ClipboardMap::Clear() { | 123 void ClipboardMap::Clear() { |
| 124 JNIEnv* env = AttachCurrentThread(); | 124 JNIEnv* env = AttachCurrentThread(); |
| 125 base::AutoLock lock(lock_); | 125 base::AutoLock lock(lock_); |
| 126 map_.clear(); | 126 map_.clear(); |
| 127 Java_Clipboard_setText(env, clipboard_manager_.obj(), NULL); | 127 Java_Clipboard_setText(env, clipboard_manager_.obj(), NULL); |
| 128 } | 128 } |
| 129 | 129 |
| 130 // If the internal map contains a plain-text entry and it does not match that | 130 // If the internal map contains a plain-text entry and it does not match that |
| 131 // in the Android clipboard, clear the map and insert the Android text into it. | 131 // in the Android clipboard, clear the map and insert the Android text into it. |
|
joth
2013/11/12 01:45:39
this comment sounds out of date (well, incomplete)
Kristian Monsen
2013/11/12 04:27:23
Done.
| |
| 132 void ClipboardMap::SyncWithAndroidClipboard() { | 132 void ClipboardMap::SyncWithAndroidClipboard() { |
| 133 lock_.AssertAcquired(); | 133 lock_.AssertAcquired(); |
| 134 JNIEnv* env = AttachCurrentThread(); | 134 JNIEnv* env = AttachCurrentThread(); |
| 135 | 135 |
| 136 // Update the plain text clipboard entry | |
| 136 std::map<std::string, std::string>::const_iterator it = | 137 std::map<std::string, std::string>::const_iterator it = |
| 137 map_.find(kPlainTextFormat); | 138 map_.find(kPlainTextFormat); |
| 138 | 139 ScopedJavaLocalRef<jstring> java_string_text = |
| 139 if (!Java_Clipboard_hasPlainText(env, clipboard_manager_.obj())) { | 140 Java_Clipboard_getCoercedText(env, clipboard_manager_.obj()); |
| 140 if (it != map_.end()) | 141 if (java_string_text.obj()) { |
| 142 std::string android_string = ConvertJavaStringToUTF8(java_string_text); | |
| 143 if (it == map_.end() || it->second != android_string) { | |
|
joth
2013/11/12 01:45:39
the change from hasPlainText() method to the code
Kristian Monsen
2013/11/12 04:27:23
I mostly did not want to quit when there was not p
| |
| 144 // There is a different string in the Android clipboard than we have. | |
| 145 // Clear the map on our side. | |
| 146 map_.clear(); | |
| 147 map_[kPlainTextFormat] = android_string; | |
| 148 } | |
| 149 } else { | |
| 150 if (it != map_.end()) { | |
| 141 // We have plain text on this side, but Android doesn't. Nuke ours. | 151 // We have plain text on this side, but Android doesn't. Nuke ours. |
| 142 map_.clear(); | 152 map_.clear(); |
| 143 return; | 153 } |
| 144 } | 154 } |
| 145 | 155 |
| 146 ScopedJavaLocalRef<jstring> java_string = | 156 // Update the html clipboard entry |
| 147 Java_Clipboard_getCoercedText(env, clipboard_manager_.obj()); | 157 ScopedJavaLocalRef<jstring> java_string_html = |
| 148 | 158 Java_Clipboard_getHtmlText(env, clipboard_manager_.obj()); |
| 149 if (!java_string.obj()) { | 159 if (java_string_html.obj()) { |
| 150 // Tolerate a null value from the Java side, even though that should not | 160 map_[kHTMLFormat] = ConvertJavaStringToUTF8(java_string_html); |
|
joth
2013/11/12 01:45:39
the memory overhead of stashing two copies of ever
Kristian Monsen
2013/11/12 04:27:23
We don't really need the map as I understand, can
| |
| 151 // happen since hasPlainText has already returned true. | |
| 152 // Should only happen if someone is using the clipboard on multiple | |
| 153 // threads and clears it out after hasPlainText but before we get here... | |
| 154 if (it != map_.end()) | |
| 155 // We have plain text on this side, but Android doesn't. Nuke ours. | |
| 156 map_.clear(); | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 // If Android text differs from ours (or we have none), then copy Android's. | |
| 161 std::string android_string = ConvertJavaStringToUTF8(java_string); | |
| 162 if (it == map_.end() || it->second != android_string) { | |
| 163 map_.clear(); | |
| 164 map_[kPlainTextFormat] = android_string; | |
| 165 } | 161 } |
| 166 } | 162 } |
| 167 | 163 |
| 168 } // namespace | 164 } // namespace |
| 169 | 165 |
| 170 Clipboard::FormatType::FormatType() { | 166 Clipboard::FormatType::FormatType() { |
| 171 } | 167 } |
| 172 | 168 |
| 173 Clipboard::FormatType::FormatType(const std::string& native_format) | 169 Clipboard::FormatType::FormatType(const std::string& native_format) |
| 174 : data_(native_format) { | 170 : data_(native_format) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 193 | 189 |
| 194 Clipboard::Clipboard() { | 190 Clipboard::Clipboard() { |
| 195 DCHECK(CalledOnValidThread()); | 191 DCHECK(CalledOnValidThread()); |
| 196 } | 192 } |
| 197 | 193 |
| 198 Clipboard::~Clipboard() { | 194 Clipboard::~Clipboard() { |
| 199 DCHECK(CalledOnValidThread()); | 195 DCHECK(CalledOnValidThread()); |
| 200 } | 196 } |
| 201 | 197 |
| 202 // Main entry point used to write several values in the clipboard. | 198 // Main entry point used to write several values in the clipboard. |
| 203 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { | 199 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { |
| 204 DCHECK(CalledOnValidThread()); | 200 DCHECK(CalledOnValidThread()); |
| 205 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 201 DCHECK_EQ(buffer, BUFFER_STANDARD); |
|
joth
2013/11/12 01:45:39
are all these edits from here down intended? look
Kristian Monsen
2013/11/12 02:17:36
No, need a manual merge here. Will fix.
| |
| 206 g_map.Get().Clear(); | 202 g_map.Get().Clear(); |
| 207 for (ObjectMap::const_iterator iter = objects.begin(); | 203 for (ObjectMap::const_iterator iter = objects.begin(); |
| 208 iter != objects.end(); ++iter) { | 204 iter != objects.end(); ++iter) { |
| 209 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 205 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 210 } | 206 } |
| 211 } | 207 } |
| 212 | 208 |
| 213 uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) { | 209 uint64 Clipboard::GetSequenceNumber(Clipboard::Buffer /* buffer */) { |
| 214 DCHECK(CalledOnValidThread()); | 210 DCHECK(CalledOnValidThread()); |
| 215 // TODO: implement this. For now this interface will advertise | 211 // TODO: implement this. For now this interface will advertise |
| 216 // that the clipboard never changes. That's fine as long as we | 212 // that the clipboard never changes. That's fine as long as we |
| 217 // don't rely on this signal. | 213 // don't rely on this signal. |
| 218 return 0; | 214 return 0; |
| 219 } | 215 } |
| 220 | 216 |
| 221 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 217 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
| 222 ClipboardType type) const { | 218 Clipboard::Buffer buffer) const { |
| 223 DCHECK(CalledOnValidThread()); | 219 DCHECK(CalledOnValidThread()); |
| 224 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 220 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 225 return g_map.Get().HasFormat(format.data()); | 221 return g_map.Get().HasFormat(format.data()); |
| 226 } | 222 } |
| 227 | 223 |
| 228 void Clipboard::Clear(ClipboardType type) { | 224 void Clipboard::Clear(Buffer buffer) { |
| 229 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
| 230 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 226 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 231 g_map.Get().Clear(); | 227 g_map.Get().Clear(); |
| 232 } | 228 } |
| 233 | 229 |
| 234 void Clipboard::ReadAvailableTypes(ClipboardType type, | 230 void Clipboard::ReadAvailableTypes(Buffer buffer, std::vector<string16>* types, |
| 235 std::vector<string16>* types, | |
| 236 bool* contains_filenames) const { | 231 bool* contains_filenames) const { |
| 237 DCHECK(CalledOnValidThread()); | 232 DCHECK(CalledOnValidThread()); |
| 238 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 233 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 239 | 234 |
| 240 if (!types || !contains_filenames) { | 235 if (!types || !contains_filenames) { |
| 241 NOTREACHED(); | 236 NOTREACHED(); |
| 242 return; | 237 return; |
| 243 } | 238 } |
| 244 | 239 |
| 245 NOTIMPLEMENTED(); | 240 NOTIMPLEMENTED(); |
| 246 | 241 |
| 247 types->clear(); | 242 types->clear(); |
| 248 *contains_filenames = false; | 243 *contains_filenames = false; |
| 249 } | 244 } |
| 250 | 245 |
| 251 void Clipboard::ReadText(ClipboardType type, string16* result) const { | 246 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { |
| 252 DCHECK(CalledOnValidThread()); | 247 DCHECK(CalledOnValidThread()); |
| 253 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 248 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 254 std::string utf8; | 249 std::string utf8; |
| 255 ReadAsciiText(type, &utf8); | 250 ReadAsciiText(buffer, &utf8); |
| 256 *result = UTF8ToUTF16(utf8); | 251 *result = UTF8ToUTF16(utf8); |
| 257 } | 252 } |
| 258 | 253 |
| 259 void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { | 254 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, |
| 255 std::string* result) const { | |
| 260 DCHECK(CalledOnValidThread()); | 256 DCHECK(CalledOnValidThread()); |
| 261 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 257 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 262 *result = g_map.Get().Get(kPlainTextFormat); | 258 *result = g_map.Get().Get(kPlainTextFormat); |
| 263 } | 259 } |
| 264 | 260 |
| 265 // Note: |src_url| isn't really used. It is only implemented in Windows | 261 // Note: |src_url| isn't really used. It is only implemented in Windows |
| 266 void Clipboard::ReadHTML(ClipboardType type, | 262 void Clipboard::ReadHTML(Clipboard::Buffer buffer, |
| 267 string16* markup, | 263 string16* markup, |
| 268 std::string* src_url, | 264 std::string* src_url, |
| 269 uint32* fragment_start, | 265 uint32* fragment_start, |
| 270 uint32* fragment_end) const { | 266 uint32* fragment_end) const { |
| 271 DCHECK(CalledOnValidThread()); | 267 DCHECK(CalledOnValidThread()); |
| 272 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 268 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 273 if (src_url) | 269 if (src_url) |
| 274 src_url->clear(); | 270 src_url->clear(); |
| 275 | 271 |
| 276 std::string input = g_map.Get().Get(kHTMLFormat); | 272 std::string input = g_map.Get().Get(kHTMLFormat); |
| 277 *markup = UTF8ToUTF16(input); | 273 *markup = UTF8ToUTF16(input); |
| 278 | 274 |
| 279 *fragment_start = 0; | 275 *fragment_start = 0; |
| 280 *fragment_end = static_cast<uint32>(markup->length()); | 276 *fragment_end = static_cast<uint32>(markup->length()); |
| 281 } | 277 } |
| 282 | 278 |
| 283 void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { | 279 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { |
| 284 DCHECK(CalledOnValidThread()); | 280 DCHECK(CalledOnValidThread()); |
| 285 NOTIMPLEMENTED(); | 281 NOTIMPLEMENTED(); |
| 286 } | 282 } |
| 287 | 283 |
| 288 SkBitmap Clipboard::ReadImage(ClipboardType type) const { | 284 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 289 DCHECK(CalledOnValidThread()); | 285 DCHECK(CalledOnValidThread()); |
| 290 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 286 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 291 std::string input = g_map.Get().Get(kBitmapFormat); | 287 std::string input = g_map.Get().Get(kBitmapFormat); |
| 292 | 288 |
| 293 SkBitmap bmp; | 289 SkBitmap bmp; |
| 294 if (!input.empty()) { | 290 if (!input.empty()) { |
| 295 DCHECK_LE(sizeof(gfx::Size), input.size()); | 291 DCHECK_LE(sizeof(gfx::Size), input.size()); |
| 296 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data()); | 292 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data()); |
| 297 | 293 |
| 298 bmp.setConfig( | 294 bmp.setConfig( |
| 299 SkBitmap::kARGB_8888_Config, size->width(), size->height(), 0); | 295 SkBitmap::kARGB_8888_Config, size->width(), size->height(), 0); |
| 300 bmp.allocPixels(); | 296 bmp.allocPixels(); |
| 301 | 297 |
| 302 int bm_size = size->width() * size->height() * 4; | 298 int bm_size = size->width() * size->height() * 4; |
| 303 DCHECK_EQ(sizeof(gfx::Size) + bm_size, input.size()); | 299 DCHECK_EQ(sizeof(gfx::Size) + bm_size, input.size()); |
| 304 | 300 |
| 305 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bm_size); | 301 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bm_size); |
| 306 } | 302 } |
| 307 return bmp; | 303 return bmp; |
| 308 } | 304 } |
| 309 | 305 |
| 310 void Clipboard::ReadCustomData(ClipboardType clipboard_type, | 306 void Clipboard::ReadCustomData(Buffer buffer, |
| 311 const string16& type, | 307 const string16& type, |
| 312 string16* result) const { | 308 string16* result) const { |
| 313 DCHECK(CalledOnValidThread()); | 309 DCHECK(CalledOnValidThread()); |
| 314 NOTIMPLEMENTED(); | 310 NOTIMPLEMENTED(); |
| 315 } | 311 } |
| 316 | 312 |
| 317 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 313 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 318 DCHECK(CalledOnValidThread()); | 314 DCHECK(CalledOnValidThread()); |
| 319 NOTIMPLEMENTED(); | 315 NOTIMPLEMENTED(); |
| 320 } | 316 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 const char* data_data, size_t data_len) { | 420 const char* data_data, size_t data_len) { |
| 425 g_map.Get().Set(format.data(), std::string(data_data, data_len)); | 421 g_map.Get().Set(format.data(), std::string(data_data, data_len)); |
| 426 } | 422 } |
| 427 | 423 |
| 428 // See clipboard_android_initialization.h for more information. | 424 // See clipboard_android_initialization.h for more information. |
| 429 bool RegisterClipboardAndroid(JNIEnv* env) { | 425 bool RegisterClipboardAndroid(JNIEnv* env) { |
| 430 return RegisterNativesImpl(env); | 426 return RegisterNativesImpl(env); |
| 431 } | 427 } |
| 432 | 428 |
| 433 } // namespace ui | 429 } // namespace ui |
| OLD | NEW |