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_android.h" | 5 #include "ui/base/clipboard/clipboard_android.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/android/context_utils.h" | 9 #include "base/android/context_utils.h" |
| 10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
| 11 #include "base/android/scoped_java_ref.h" | |
| 11 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
| 16 #include "base/time/time.h" | |
| 15 #include "jni/Clipboard_jni.h" | 17 #include "jni/Clipboard_jni.h" |
| 16 #include "third_party/skia/include/core/SkBitmap.h" | 18 #include "third_party/skia/include/core/SkBitmap.h" |
| 17 #include "ui/gfx/geometry/size.h" | 19 #include "ui/gfx/geometry/size.h" |
| 18 | 20 |
| 19 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, | 21 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, |
| 20 // HTML+text now that Android's clipboard system supports them, then nuke the | 22 // HTML+text now that Android's clipboard system supports them, then nuke the |
| 21 // legacy implementation note below. | 23 // legacy implementation note below. |
| 22 | 24 |
| 23 // Legacy implementation note: | 25 // Legacy implementation note: |
| 24 // The Android clipboard system used to only support text format. So we used the | 26 // The Android clipboard system used to only support text format. So we used the |
| 25 // Android system when some text was added or retrieved from the system. For | 27 // Android system when some text was added or retrieved from the system. For |
| 26 // anything else, we STILL store the value in some process wide static | 28 // anything else, we STILL store the value in some process wide static |
| 27 // variable protected by a lock. So the (non-text) clipboard will only work | 29 // variable protected by a lock. So the (non-text) clipboard will only work |
| 28 // within the same process. | 30 // within the same process. |
| 29 | 31 |
| 30 using base::android::AttachCurrentThread; | 32 using base::android::AttachCurrentThread; |
| 31 using base::android::ClearException; | 33 using base::android::ClearException; |
| 32 using base::android::ConvertJavaStringToUTF8; | 34 using base::android::ConvertJavaStringToUTF8; |
| 33 using base::android::ConvertUTF8ToJavaString; | 35 using base::android::ConvertUTF8ToJavaString; |
| 34 using base::android::ScopedJavaGlobalRef; | 36 using base::android::ScopedJavaGlobalRef; |
| 35 using base::android::ScopedJavaLocalRef; | 37 using base::android::ScopedJavaLocalRef; |
| 36 | 38 |
| 37 namespace ui { | 39 namespace ui { |
| 38 | 40 |
| 39 namespace { | 41 namespace { |
| 42 | |
| 40 // Various formats we support. | 43 // Various formats we support. |
| 41 const char kURLFormat[] = "url"; | 44 const char kURLFormat[] = "url"; |
| 42 const char kPlainTextFormat[] = "text"; | 45 const char kPlainTextFormat[] = "text"; |
| 43 const char kHTMLFormat[] = "html"; | 46 const char kHTMLFormat[] = "html"; |
| 44 const char kRTFFormat[] = "rtf"; | 47 const char kRTFFormat[] = "rtf"; |
| 45 const char kBitmapFormat[] = "bitmap"; | 48 const char kBitmapFormat[] = "bitmap"; |
| 46 const char kWebKitSmartPasteFormat[] = "webkit_smart"; | 49 const char kWebKitSmartPasteFormat[] = "webkit_smart"; |
| 47 const char kBookmarkFormat[] = "bookmark"; | 50 const char kBookmarkFormat[] = "bookmark"; |
| 48 | 51 |
| 49 class ClipboardMap { | 52 class ClipboardMap { |
| 50 public: | 53 public: |
| 51 ClipboardMap(); | 54 ClipboardMap(); |
| 52 std::string Get(const std::string& format); | 55 std::string Get(const std::string& format); |
| 53 int64_t GetLastClipboardChangeTimeInMillis(); | 56 uint64_t GetSequenceNumber() const; |
| 57 base::Time GetLastModifiedTime() const; | |
| 58 void ClearLastModifiedTime(); | |
| 54 bool HasFormat(const std::string& format); | 59 bool HasFormat(const std::string& format); |
| 60 void OnPrimaryClipboardChanged(); | |
| 55 void Set(const std::string& format, const std::string& data); | 61 void Set(const std::string& format, const std::string& data); |
| 56 void CommitToAndroidClipboard(); | 62 void CommitToAndroidClipboard(); |
| 57 void Clear(); | 63 void Clear(); |
| 58 | 64 |
| 59 private: | 65 private: |
| 60 void UpdateFromAndroidClipboard(); | 66 void UpdateFromAndroidClipboard(); |
| 61 std::map<std::string, std::string> map_; | 67 std::map<std::string, std::string> map_; |
| 68 bool map_up_to_date_; | |
| 62 base::Lock lock_; | 69 base::Lock lock_; |
| 63 | 70 |
| 64 int64_t last_clipboard_change_time_ms_; | 71 uint64_t sequence_number_; |
| 72 base::Time last_modified_time_; | |
| 65 | 73 |
| 66 // Java class and methods for the Android ClipboardManager. | 74 // Java class and methods for the Android ClipboardManager. |
| 67 ScopedJavaGlobalRef<jobject> clipboard_manager_; | 75 ScopedJavaGlobalRef<jobject> clipboard_manager_; |
| 68 }; | 76 }; |
| 69 base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; | 77 base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; |
| 70 | 78 |
| 71 ClipboardMap::ClipboardMap() { | 79 ClipboardMap::ClipboardMap() { |
| 72 clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread())); | 80 clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread())); |
| 73 DCHECK(clipboard_manager_.obj()); | 81 DCHECK(clipboard_manager_.obj()); |
| 82 map_up_to_date_ = false; | |
|
dcheng
2017/04/13 20:35:37
Nit: use the initializer list (or use in-class ini
Mark P
2017/04/13 20:54:05
Done.
| |
| 74 } | 83 } |
| 75 | 84 |
| 76 std::string ClipboardMap::Get(const std::string& format) { | 85 std::string ClipboardMap::Get(const std::string& format) { |
| 77 base::AutoLock lock(lock_); | 86 base::AutoLock lock(lock_); |
| 78 UpdateFromAndroidClipboard(); | 87 UpdateFromAndroidClipboard(); |
| 79 std::map<std::string, std::string>::const_iterator it = map_.find(format); | 88 std::map<std::string, std::string>::const_iterator it = map_.find(format); |
| 80 return it == map_.end() ? std::string() : it->second; | 89 return it == map_.end() ? std::string() : it->second; |
| 81 } | 90 } |
| 82 | 91 |
| 83 int64_t ClipboardMap::GetLastClipboardChangeTimeInMillis() { | 92 uint64_t ClipboardMap::GetSequenceNumber() const { |
| 84 base::AutoLock lock(lock_); | 93 return sequence_number_; |
| 85 UpdateFromAndroidClipboard(); | 94 } |
| 86 return last_clipboard_change_time_ms_; | 95 |
| 96 base::Time ClipboardMap::GetLastModifiedTime() const { | |
| 97 return last_modified_time_; | |
| 98 } | |
| 99 | |
| 100 void ClipboardMap::ClearLastModifiedTime() { | |
| 101 last_modified_time_ = base::Time(); | |
| 87 } | 102 } |
| 88 | 103 |
| 89 bool ClipboardMap::HasFormat(const std::string& format) { | 104 bool ClipboardMap::HasFormat(const std::string& format) { |
| 90 base::AutoLock lock(lock_); | 105 base::AutoLock lock(lock_); |
| 91 UpdateFromAndroidClipboard(); | 106 UpdateFromAndroidClipboard(); |
| 92 return base::ContainsKey(map_, format); | 107 return base::ContainsKey(map_, format); |
| 93 } | 108 } |
| 94 | 109 |
| 110 void ClipboardMap::OnPrimaryClipboardChanged() { | |
| 111 sequence_number_++; | |
| 112 last_modified_time_ = base::Time::Now(); | |
| 113 map_up_to_date_ = false; | |
| 114 } | |
| 115 | |
| 95 void ClipboardMap::Set(const std::string& format, const std::string& data) { | 116 void ClipboardMap::Set(const std::string& format, const std::string& data) { |
| 96 base::AutoLock lock(lock_); | 117 base::AutoLock lock(lock_); |
| 97 map_[format] = data; | 118 map_[format] = data; |
| 119 map_up_to_date_ = false; | |
|
dcheng
2017/04/13 20:35:37
Can we make this a tri-state enum? Calling UpdateF
Mark P
2017/04/13 20:54:05
Do you mean
MAP_OUT_OF_DATE
MAP_FRESHER_THAN_JAVA
dcheng
2017/04/13 20:59:18
MAP_OUT_OF_DATE
MAP_UP_TO_DATE
MAP_PREPARING_COMMI
Mark P
2017/04/13 21:21:46
Done with the scoped enum. Please take a look.
T
| |
| 98 } | 120 } |
| 99 | 121 |
| 100 void ClipboardMap::CommitToAndroidClipboard() { | 122 void ClipboardMap::CommitToAndroidClipboard() { |
| 101 JNIEnv* env = AttachCurrentThread(); | 123 JNIEnv* env = AttachCurrentThread(); |
| 102 base::AutoLock lock(lock_); | 124 base::AutoLock lock(lock_); |
| 103 if (base::ContainsKey(map_, kHTMLFormat)) { | 125 if (base::ContainsKey(map_, kHTMLFormat)) { |
| 104 // Android's API for storing HTML content on the clipboard requires a plain- | 126 // Android's API for storing HTML content on the clipboard requires a plain- |
| 105 // text representation to be available as well. | 127 // text representation to be available as well. |
| 106 if (!base::ContainsKey(map_, kPlainTextFormat)) | 128 if (!base::ContainsKey(map_, kPlainTextFormat)) |
| 107 return; | 129 return; |
| 108 | 130 |
| 109 ScopedJavaLocalRef<jstring> html = | 131 ScopedJavaLocalRef<jstring> html = |
| 110 ConvertUTF8ToJavaString(env, map_[kHTMLFormat]); | 132 ConvertUTF8ToJavaString(env, map_[kHTMLFormat]); |
| 111 ScopedJavaLocalRef<jstring> text = | 133 ScopedJavaLocalRef<jstring> text = |
| 112 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); | 134 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); |
| 113 | 135 |
| 114 DCHECK(html.obj() && text.obj()); | 136 DCHECK(html.obj() && text.obj()); |
| 115 Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text); | 137 Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text); |
| 116 } else if (base::ContainsKey(map_, kPlainTextFormat)) { | 138 } else if (base::ContainsKey(map_, kPlainTextFormat)) { |
| 117 ScopedJavaLocalRef<jstring> str = | 139 ScopedJavaLocalRef<jstring> str = |
| 118 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); | 140 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); |
| 119 DCHECK(str.obj()); | 141 DCHECK(str.obj()); |
| 120 Java_Clipboard_setText(env, clipboard_manager_, str); | 142 Java_Clipboard_setText(env, clipboard_manager_, str); |
| 121 } else { | 143 } else { |
| 122 Java_Clipboard_clear(env, clipboard_manager_); | 144 Java_Clipboard_clear(env, clipboard_manager_); |
| 123 NOTIMPLEMENTED(); | 145 NOTIMPLEMENTED(); |
| 124 } | 146 } |
| 147 map_up_to_date_ = true; | |
| 148 sequence_number_++; | |
| 149 last_modified_time_ = base::Time::Now(); | |
| 125 } | 150 } |
| 126 | 151 |
| 127 void ClipboardMap::Clear() { | 152 void ClipboardMap::Clear() { |
| 128 JNIEnv* env = AttachCurrentThread(); | 153 JNIEnv* env = AttachCurrentThread(); |
| 129 base::AutoLock lock(lock_); | 154 base::AutoLock lock(lock_); |
| 130 map_.clear(); | 155 map_.clear(); |
| 131 Java_Clipboard_clear(env, clipboard_manager_); | 156 Java_Clipboard_clear(env, clipboard_manager_); |
| 157 map_up_to_date_ = true; | |
| 158 sequence_number_++; | |
| 159 last_modified_time_ = base::Time::Now(); | |
| 132 } | 160 } |
| 133 | 161 |
| 134 // Add a key:jstr pair to map, but only if jstr is not null, and also | 162 // Add a key:jstr pair to map, but only if jstr is not null, and also |
| 135 // not empty. | 163 // not empty. |
| 136 void AddMapEntry(JNIEnv* env, | 164 void AddMapEntry(JNIEnv* env, |
| 137 std::map<std::string, std::string>* map, | 165 std::map<std::string, std::string>* map, |
| 138 const char* key, | 166 const char* key, |
| 139 const ScopedJavaLocalRef<jstring>& jstr) { | 167 const ScopedJavaLocalRef<jstring>& jstr) { |
| 140 if (!jstr.is_null()) { | 168 if (!jstr.is_null()) { |
| 141 std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); | 169 std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); |
| 142 if (!str.empty()) | 170 if (!str.empty()) |
| 143 (*map)[key] = str; | 171 (*map)[key] = str; |
| 144 } | 172 } |
| 145 } | 173 } |
| 146 | 174 |
| 147 // Return true if all the key-value pairs in map1 are also in map2. | 175 void ClipboardMap::UpdateFromAndroidClipboard() { |
| 148 bool MapIsSubset(const std::map<std::string, std::string>& map1, | 176 if (map_up_to_date_) |
| 149 const std::map<std::string, std::string>& map2) { | 177 return; |
| 150 for (const auto& val : map1) { | |
| 151 auto iter = map2.find(val.first); | |
| 152 if (iter == map2.end() || iter->second != val.second) | |
| 153 return false; | |
| 154 } | |
| 155 return true; | |
| 156 } | |
| 157 | 178 |
| 158 void ClipboardMap::UpdateFromAndroidClipboard() { | 179 // Fetch the current Android clipboard state. |
| 159 // Fetch the current Android clipboard state. Replace our state with | |
| 160 // the Android state if the Android state has been changed. | |
| 161 lock_.AssertAcquired(); | 180 lock_.AssertAcquired(); |
| 162 JNIEnv* env = AttachCurrentThread(); | 181 JNIEnv* env = AttachCurrentThread(); |
| 163 | 182 |
| 164 std::map<std::string, std::string> android_clipboard_state; | |
| 165 | |
| 166 ScopedJavaLocalRef<jstring> jtext = | 183 ScopedJavaLocalRef<jstring> jtext = |
| 167 Java_Clipboard_getCoercedText(env, clipboard_manager_); | 184 Java_Clipboard_getCoercedText(env, clipboard_manager_); |
| 168 ScopedJavaLocalRef<jstring> jhtml = | 185 ScopedJavaLocalRef<jstring> jhtml = |
| 169 Java_Clipboard_getHTMLText(env, clipboard_manager_); | 186 Java_Clipboard_getHTMLText(env, clipboard_manager_); |
| 170 | 187 |
| 171 AddMapEntry(env, &android_clipboard_state, kPlainTextFormat, jtext); | 188 AddMapEntry(env, &map_, kPlainTextFormat, jtext); |
| 172 AddMapEntry(env, &android_clipboard_state, kHTMLFormat, jhtml); | 189 AddMapEntry(env, &map_, kHTMLFormat, jhtml); |
| 173 last_clipboard_change_time_ms_ = | |
| 174 Java_Clipboard_getClipboardContentChangeTimeInMillis(env, | |
| 175 clipboard_manager_); | |
| 176 | 190 |
| 177 if (!MapIsSubset(android_clipboard_state, map_)) | 191 map_up_to_date_ = true; |
| 178 android_clipboard_state.swap(map_); | |
| 179 } | 192 } |
| 180 | 193 |
| 181 } // namespace | 194 } // namespace |
| 182 | 195 |
| 183 // Clipboard::FormatType implementation. | 196 // Clipboard::FormatType implementation. |
| 184 Clipboard::FormatType::FormatType() { | 197 Clipboard::FormatType::FormatType() { |
| 185 } | 198 } |
| 186 | 199 |
| 187 Clipboard::FormatType::FormatType(const std::string& native_format) | 200 Clipboard::FormatType::FormatType(const std::string& native_format) |
| 188 : data_(native_format) { | 201 : data_(native_format) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 return type; | 283 return type; |
| 271 } | 284 } |
| 272 | 285 |
| 273 // Clipboard factory method. | 286 // Clipboard factory method. |
| 274 // static | 287 // static |
| 275 Clipboard* Clipboard::Create() { | 288 Clipboard* Clipboard::Create() { |
| 276 return new ClipboardAndroid; | 289 return new ClipboardAndroid; |
| 277 } | 290 } |
| 278 | 291 |
| 279 // ClipboardAndroid implementation. | 292 // ClipboardAndroid implementation. |
| 293 | |
| 294 void ClipboardAndroid::OnPrimaryClipChanged( | |
| 295 JNIEnv* env, | |
| 296 const base::android::JavaParamRef<jobject>& obj) { | |
| 297 g_map.Get().OnPrimaryClipboardChanged(); | |
| 298 } | |
| 299 | |
| 280 ClipboardAndroid::ClipboardAndroid() { | 300 ClipboardAndroid::ClipboardAndroid() { |
| 281 DCHECK(CalledOnValidThread()); | 301 DCHECK(CalledOnValidThread()); |
| 282 } | 302 } |
| 283 | 303 |
| 284 ClipboardAndroid::~ClipboardAndroid() { | 304 ClipboardAndroid::~ClipboardAndroid() { |
| 285 DCHECK(CalledOnValidThread()); | 305 DCHECK(CalledOnValidThread()); |
| 286 } | 306 } |
| 287 | 307 |
| 288 void ClipboardAndroid::OnPreShutdown() {} | 308 void ClipboardAndroid::OnPreShutdown() {} |
| 289 | 309 |
| 290 uint64_t ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) const { | 310 uint64_t ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) const { |
| 291 DCHECK(CalledOnValidThread()); | 311 DCHECK(CalledOnValidThread()); |
| 292 // TODO: implement this. For now this interface will advertise | 312 return g_map.Get().GetSequenceNumber(); |
| 293 // that the clipboard never changes. That's fine as long as we | |
| 294 // don't rely on this signal. | |
| 295 return 0; | |
| 296 } | 313 } |
| 297 | 314 |
| 298 bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format, | 315 bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format, |
| 299 ClipboardType type) const { | 316 ClipboardType type) const { |
| 300 DCHECK(CalledOnValidThread()); | 317 DCHECK(CalledOnValidThread()); |
| 301 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 318 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 302 return g_map.Get().HasFormat(format.ToString()); | 319 return g_map.Get().HasFormat(format.ToString()); |
| 303 } | 320 } |
| 304 | 321 |
| 305 void ClipboardAndroid::Clear(ClipboardType type) { | 322 void ClipboardAndroid::Clear(ClipboardType type) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 DCHECK(CalledOnValidThread()); | 424 DCHECK(CalledOnValidThread()); |
| 408 NOTIMPLEMENTED(); | 425 NOTIMPLEMENTED(); |
| 409 } | 426 } |
| 410 | 427 |
| 411 void ClipboardAndroid::ReadData(const Clipboard::FormatType& format, | 428 void ClipboardAndroid::ReadData(const Clipboard::FormatType& format, |
| 412 std::string* result) const { | 429 std::string* result) const { |
| 413 DCHECK(CalledOnValidThread()); | 430 DCHECK(CalledOnValidThread()); |
| 414 *result = g_map.Get().Get(format.ToString()); | 431 *result = g_map.Get().Get(format.ToString()); |
| 415 } | 432 } |
| 416 | 433 |
| 417 base::Time ClipboardAndroid::GetClipboardLastModifiedTime() const { | 434 base::Time ClipboardAndroid::GetLastModifiedTime() const { |
| 418 DCHECK(CalledOnValidThread()); | 435 DCHECK(CalledOnValidThread()); |
| 419 return base::Time::FromJavaTime( | 436 return g_map.Get().GetLastModifiedTime(); |
| 420 g_map.Get().GetLastClipboardChangeTimeInMillis()); | 437 } |
| 438 | |
| 439 void ClipboardAndroid::ClearLastModifiedTime() { | |
| 440 DCHECK(CalledOnValidThread()); | |
| 441 g_map.Get().ClearLastModifiedTime(); | |
| 421 } | 442 } |
| 422 | 443 |
| 423 // Main entry point used to write several values in the clipboard. | 444 // Main entry point used to write several values in the clipboard. |
| 424 void ClipboardAndroid::WriteObjects(ClipboardType type, | 445 void ClipboardAndroid::WriteObjects(ClipboardType type, |
| 425 const ObjectMap& objects) { | 446 const ObjectMap& objects) { |
| 426 DCHECK(CalledOnValidThread()); | 447 DCHECK(CalledOnValidThread()); |
| 427 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 448 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 428 g_map.Get().Clear(); | 449 g_map.Get().Clear(); |
| 429 | 450 |
| 430 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end(); | 451 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 } | 499 } |
| 479 g_map.Get().Set(kBitmapFormat, packed); | 500 g_map.Get().Set(kBitmapFormat, packed); |
| 480 } | 501 } |
| 481 | 502 |
| 482 void ClipboardAndroid::WriteData(const Clipboard::FormatType& format, | 503 void ClipboardAndroid::WriteData(const Clipboard::FormatType& format, |
| 483 const char* data_data, | 504 const char* data_data, |
| 484 size_t data_len) { | 505 size_t data_len) { |
| 485 g_map.Get().Set(format.ToString(), std::string(data_data, data_len)); | 506 g_map.Get().Set(format.ToString(), std::string(data_data, data_len)); |
| 486 } | 507 } |
| 487 | 508 |
| 509 bool RegisterClipboardAndroid(JNIEnv* env) { | |
| 510 return RegisterNativesImpl(env); | |
| 511 } | |
| 512 | |
| 513 // Returns a pointer to the current ClipboardAndroid object. | |
| 514 static jlong Init(JNIEnv* env, | |
| 515 const base::android::JavaParamRef<jobject>& obj) { | |
| 516 return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread()); | |
| 517 } | |
| 518 | |
| 488 } // namespace ui | 519 } // namespace ui |
| OLD | NEW |