Index: ui/base/clipboard/clipboard_android.cc |
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc |
index 8f35282acde0eb701fedebef5ec6aaaad0e84243..7e2fce29ccd1f0e38dd297e061abecb575ca8bba 100644 |
--- a/ui/base/clipboard/clipboard_android.cc |
+++ b/ui/base/clipboard/clipboard_android.cc |
@@ -8,10 +8,13 @@ |
#include "base/android/context_utils.h" |
#include "base/android/jni_string.h" |
+#include "base/android/scoped_java_ref.h" |
#include "base/lazy_instance.h" |
#include "base/stl_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/synchronization/lock.h" |
+#include "base/time/time.h" |
+#include "components/prefs/pref_registry_simple.h" |
#include "jni/Clipboard_jni.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "ui/gfx/geometry/size.h" |
@@ -37,6 +40,9 @@ using base::android::ScopedJavaLocalRef; |
namespace ui { |
namespace { |
+ |
+const char kClipboardLastModifiedTimePref[] = "ui.clipboard.last_modified_time"; |
+ |
// Various formats we support. |
const char kURLFormat[] = "url"; |
const char kPlainTextFormat[] = "text"; |
@@ -50,18 +56,23 @@ class ClipboardMap { |
public: |
ClipboardMap(); |
std::string Get(const std::string& format); |
- int64_t GetLastClipboardChangeTimeInMillis(); |
+ uint64_t GetSequenceNumber() const; |
+ base::Time GetClipboardLastModifiedTime() const; |
+ void ClearClipboardLastModifiedTime(); |
dcheng
2017/04/12 00:56:09
Ditto: omit Clipboard in the names here.
Mark P
2017/04/12 21:33:51
Done.
|
bool HasFormat(const std::string& format); |
+ void OnPrimaryClipboardChanged(); |
void Set(const std::string& format, const std::string& data); |
void CommitToAndroidClipboard(); |
void Clear(); |
private: |
void UpdateFromAndroidClipboard(); |
+ void UpdateLastModifiedTimePref(); |
std::map<std::string, std::string> map_; |
base::Lock lock_; |
- int64_t last_clipboard_change_time_ms_; |
+ uint64_t sequence_number_; |
+ base::Time clipboard_last_modified_time_; |
dcheng
2017/04/12 00:56:09
Nit: no clipboard_
Mark P
2017/04/12 21:33:51
Done.
|
// Java class and methods for the Android ClipboardManager. |
ScopedJavaGlobalRef<jobject> clipboard_manager_; |
@@ -71,27 +82,44 @@ base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; |
ClipboardMap::ClipboardMap() { |
clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread())); |
DCHECK(clipboard_manager_.obj()); |
+ UpdateFromAndroidClipboard(); |
+ // *** |
+ // Read |clipboard_last_modified_time_| as a time (in seconds) from prefs |
+ // under name |kClipboardLastModifiedTimePref|. Use 0 if the pref doesn't |
+ // exist. |
} |
std::string ClipboardMap::Get(const std::string& format) { |
base::AutoLock lock(lock_); |
- UpdateFromAndroidClipboard(); |
std::map<std::string, std::string>::const_iterator it = map_.find(format); |
return it == map_.end() ? std::string() : it->second; |
} |
-int64_t ClipboardMap::GetLastClipboardChangeTimeInMillis() { |
- base::AutoLock lock(lock_); |
- UpdateFromAndroidClipboard(); |
- return last_clipboard_change_time_ms_; |
+uint64_t ClipboardMap::GetSequenceNumber() const { |
+ return sequence_number_; |
+} |
+ |
+base::Time ClipboardMap::GetClipboardLastModifiedTime() const { |
+ return clipboard_last_modified_time_; |
+} |
+ |
+void ClipboardMap::ClearClipboardLastModifiedTime() { |
+ clipboard_last_modified_time_ = base::Time(); |
+ UpdateLastModifiedTimePref(); |
} |
bool ClipboardMap::HasFormat(const std::string& format) { |
base::AutoLock lock(lock_); |
- UpdateFromAndroidClipboard(); |
return base::ContainsKey(map_, format); |
} |
+void ClipboardMap::OnPrimaryClipboardChanged() { |
+ sequence_number_++; |
+ clipboard_last_modified_time_ = base::Time::Now(); |
+ UpdateLastModifiedTimePref(); |
+ UpdateFromAndroidClipboard(); |
dcheng
2017/04/12 00:56:09
I do wonder if we want to do this work up-front wh
Mark P
2017/04/12 04:21:11
Sure, I think I can do that pretty cleanly.
I'll m
Mark P
2017/04/12 21:33:51
Done.
|
+} |
+ |
void ClipboardMap::Set(const std::string& format, const std::string& data) { |
base::AutoLock lock(lock_); |
map_[format] = data; |
@@ -122,6 +150,9 @@ void ClipboardMap::CommitToAndroidClipboard() { |
Java_Clipboard_clear(env, clipboard_manager_); |
NOTIMPLEMENTED(); |
} |
+ sequence_number_++; |
+ clipboard_last_modified_time_ = base::Time::Now(); |
+ UpdateLastModifiedTimePref(); |
} |
void ClipboardMap::Clear() { |
@@ -129,6 +160,9 @@ void ClipboardMap::Clear() { |
base::AutoLock lock(lock_); |
map_.clear(); |
Java_Clipboard_clear(env, clipboard_manager_); |
+ sequence_number_++; |
+ clipboard_last_modified_time_ = base::Time::Now(); |
+ UpdateLastModifiedTimePref(); |
} |
// Add a key:jstr pair to map, but only if jstr is not null, and also |
@@ -144,38 +178,25 @@ void AddMapEntry(JNIEnv* env, |
} |
} |
-// Return true if all the key-value pairs in map1 are also in map2. |
-bool MapIsSubset(const std::map<std::string, std::string>& map1, |
- const std::map<std::string, std::string>& map2) { |
- for (const auto& val : map1) { |
- auto iter = map2.find(val.first); |
- if (iter == map2.end() || iter->second != val.second) |
- return false; |
- } |
- return true; |
-} |
- |
void ClipboardMap::UpdateFromAndroidClipboard() { |
- // Fetch the current Android clipboard state. Replace our state with |
- // the Android state if the Android state has been changed. |
+ // Fetch the current Android clipboard state. |
lock_.AssertAcquired(); |
JNIEnv* env = AttachCurrentThread(); |
- std::map<std::string, std::string> android_clipboard_state; |
- |
ScopedJavaLocalRef<jstring> jtext = |
Java_Clipboard_getCoercedText(env, clipboard_manager_); |
ScopedJavaLocalRef<jstring> jhtml = |
Java_Clipboard_getHTMLText(env, clipboard_manager_); |
- AddMapEntry(env, &android_clipboard_state, kPlainTextFormat, jtext); |
- AddMapEntry(env, &android_clipboard_state, kHTMLFormat, jhtml); |
- last_clipboard_change_time_ms_ = |
- Java_Clipboard_getClipboardContentChangeTimeInMillis(env, |
- clipboard_manager_); |
+ AddMapEntry(env, &map_, kPlainTextFormat, jtext); |
+ AddMapEntry(env, &map_, kHTMLFormat, jhtml); |
+} |
- if (!MapIsSubset(android_clipboard_state, map_)) |
- android_clipboard_state.swap(map_); |
+void ClipboardMap::UpdateLastModifiedTimePref() { |
+ // *** |
+ // Record |clipboard_last_modified_time_| as a time (in seconds) to prefs |
+ // under name |kClipboardLastModifiedTimePref|. Make sure that null times |
+ // get recorded as 0. |
} |
} // namespace |
@@ -277,6 +298,18 @@ Clipboard* Clipboard::Create() { |
} |
// ClipboardAndroid implementation. |
+ |
+// static |
+void ClipboardAndroid::RegisterPrefs(PrefRegistrySimple* registry) { |
+ registry->RegisterUint64Pref(kClipboardLastModifiedTimePref, 0u); |
+} |
+ |
+void ClipboardAndroid::OnPrimaryClipChanged( |
+ JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ g_map.Get().OnPrimaryClipboardChanged(); |
+} |
+ |
ClipboardAndroid::ClipboardAndroid() { |
DCHECK(CalledOnValidThread()); |
} |
@@ -289,10 +322,7 @@ void ClipboardAndroid::OnPreShutdown() {} |
uint64_t ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) const { |
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().GetSequenceNumber(); |
} |
bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format, |
@@ -416,8 +446,12 @@ void ClipboardAndroid::ReadData(const Clipboard::FormatType& format, |
base::Time ClipboardAndroid::GetClipboardLastModifiedTime() const { |
DCHECK(CalledOnValidThread()); |
- return base::Time::FromJavaTime( |
- g_map.Get().GetLastClipboardChangeTimeInMillis()); |
+ return g_map.Get().GetClipboardLastModifiedTime(); |
+} |
+ |
+void ClipboardAndroid::ClearClipboardLastModifiedTime() { |
+ DCHECK(CalledOnValidThread()); |
+ g_map.Get().ClearClipboardLastModifiedTime(); |
} |
// Main entry point used to write several values in the clipboard. |
@@ -485,4 +519,14 @@ void ClipboardAndroid::WriteData(const Clipboard::FormatType& format, |
g_map.Get().Set(format.ToString(), std::string(data_data, data_len)); |
} |
+bool RegisterClipboardAndroid(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+// Returns a pointer to the current ClipboardAndroid object. |
+static jlong Init(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread()); |
+} |
+ |
} // namespace ui |