Index: ui/base/clipboard/clipboard_android.cc |
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc |
index e5e2a960d4da4c4558f8e4c115ca8d4ab3bf285e..ea44d4538ef5da987ce35586a4089c96f5c580e2 100644 |
--- a/ui/base/clipboard/clipboard_android.cc |
+++ b/ui/base/clipboard/clipboard_android.cc |
@@ -45,7 +45,7 @@ const char kBookmarkFormat[] = "bookmark"; |
const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data"; |
const char kMimeTypeWebCustomData[] = "chromium/x-web-custom-data"; |
-class ClipboardMap { |
+class ClipboardMap : public ClipboardChangeListener { |
public: |
ClipboardMap(); |
std::string Get(const std::string& format); |
@@ -53,17 +53,23 @@ class ClipboardMap { |
void Set(const std::string& format, const std::string& data); |
void Clear(); |
+ uint64 sequence_number() const { return sequence_number_; } |
+ |
private: |
+ // Called from Java when the clipboard changes. |
+ void OnChange(JNIEnv* env, jobject obj) OVERRIDE; |
+ |
void SyncWithAndroidClipboard(); |
std::map<std::string, std::string> map_; |
base::Lock lock_; |
// Java class and methods for the Android ClipboardManager. |
ScopedJavaGlobalRef<jobject> clipboard_manager_; |
+ uint64 sequence_number_; |
}; |
base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; |
-ClipboardMap::ClipboardMap() { |
+ClipboardMap::ClipboardMap() : sequence_number_(0) { |
JNIEnv* env = AttachCurrentThread(); |
DCHECK(env); |
@@ -75,6 +81,10 @@ ClipboardMap::ClipboardMap() { |
Java_Clipboard_create(env, context); |
DCHECK(local_ref.obj()); |
clipboard_manager_.Reset(env, local_ref.Release()); |
+ |
+ Java_Clipboard_addChangeListener( |
+ env, clipboard_manager_.obj(), reinterpret_cast<intptr_t>(this)); |
+ LOG(ERROR) << "Hello?"; |
} |
std::string ClipboardMap::Get(const std::string& format) { |
@@ -127,6 +137,12 @@ void ClipboardMap::Clear() { |
Java_Clipboard_setText(env, clipboard_manager_.obj(), NULL); |
} |
+void ClipboardMap::OnChange(JNIEnv* env, jobject obj) { |
+ LOG(ERROR) << "Ping"; |
+ // TODO(dcheng): We may or may not need a lock here. |
+ ++sequence_number_; |
+} |
+ |
// If the internal map contains a plain-text entry and it does not match that |
// in the Android clipboard, clear the map and insert the Android text into it. |
// If there is an HTML entry in the Android clipboard it gets inserted in the |
@@ -223,10 +239,7 @@ void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { |
uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) { |
DCHECK(CalledOnValidThread()); |
- // TODO: implement this. For now this interface will advertise |
- // that the clipboard never changes. That's fine as long as we |
- // don't rely on this signal. |
- return 0; |
+ return g_map.Get().sequence_number(); |
} |
bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
@@ -389,6 +402,7 @@ const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
} |
void Clipboard::WriteText(const char* text_data, size_t text_len) { |
+ DCHECK(CalledOnValidThread()); |
g_map.Get().Set(kPlainTextFormat, std::string(text_data, text_len)); |
} |
@@ -396,10 +410,12 @@ void Clipboard::WriteHTML(const char* markup_data, |
size_t markup_len, |
const char* url_data, |
size_t url_len) { |
+ DCHECK(CalledOnValidThread()); |
g_map.Get().Set(kHTMLFormat, std::string(markup_data, markup_len)); |
} |
void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |
+ DCHECK(CalledOnValidThread()); |
NOTIMPLEMENTED(); |
} |
@@ -407,18 +423,21 @@ void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |
// URL spec. |
void Clipboard::WriteBookmark(const char* title_data, size_t title_len, |
const char* url_data, size_t url_len) { |
+ DCHECK(CalledOnValidThread()); |
g_map.Get().Set(kBookmarkFormat, std::string(url_data, url_len)); |
} |
// Write an extra flavor that signifies WebKit was the last to modify the |
// pasteboard. This flavor has no data. |
void Clipboard::WriteWebSmartPaste() { |
+ DCHECK(CalledOnValidThread()); |
g_map.Get().Set(kWebKitSmartPasteFormat, std::string()); |
} |
// Note: we implement this to pass all unit tests but it is currently unclear |
// how some code would consume this. |
void Clipboard::WriteBitmap(const SkBitmap& bitmap) { |
+ DCHECK(CalledOnValidThread()); |
gfx::Size size(bitmap.width(), bitmap.height()); |
std::string packed(reinterpret_cast<const char*>(&size), sizeof(size)); |
@@ -432,6 +451,7 @@ void Clipboard::WriteBitmap(const SkBitmap& bitmap) { |
void Clipboard::WriteData(const Clipboard::FormatType& format, |
const char* data_data, size_t data_len) { |
+ DCHECK(CalledOnValidThread()); |
g_map.Get().Set(format.data(), std::string(data_data, data_len)); |
} |