diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-12 14:07:37 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 10:29:26 +0000 |
commit | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (patch) | |
tree | 25cde714b2b71eb639d1cd53f5a22e9ba76e14ef /chromium/ui/base/clipboard | |
parent | bb09965444b5bb20b096a291445170876225268d (diff) | |
download | qtwebengine-chromium-ec02ee4181c49b61fce1c8fb99292dbb8139cc90.tar.gz |
BASELINE: Update Chromium to 59.0.3071.134
Change-Id: Id02ef6fb2204c5fd21668a1c3e6911c83b17585a
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ui/base/clipboard')
-rw-r--r-- | chromium/ui/base/clipboard/clipboard.cc | 12 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard.h | 17 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_android.cc | 164 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_android.h | 25 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_aura.cc | 55 |
5 files changed, 202 insertions, 71 deletions
diff --git a/chromium/ui/base/clipboard/clipboard.cc b/chromium/ui/base/clipboard/clipboard.cc index cf06e2f6642..c8c0c38d6b1 100644 --- a/chromium/ui/base/clipboard/clipboard.cc +++ b/chromium/ui/base/clipboard/clipboard.cc @@ -17,10 +17,10 @@ namespace ui { -base::LazyInstance<Clipboard::AllowedThreadsVector> +base::LazyInstance<Clipboard::AllowedThreadsVector>::DestructorAtExit Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<Clipboard::ClipboardMap> Clipboard::clipboard_map_ = - LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<Clipboard::ClipboardMap>::DestructorAtExit + Clipboard::clipboard_map_ = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<base::Lock>::Leaky Clipboard::clipboard_map_lock_ = LAZY_INSTANCE_INITIALIZER; @@ -86,6 +86,12 @@ void Clipboard::DestroyClipboardForCurrentThread() { clipboard_map->erase(it); } +base::Time Clipboard::GetLastModifiedTime() const { + return base::Time(); +} + +void Clipboard::ClearLastModifiedTime() {} + void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) { // Ignore writes with empty parameters. for (const auto& param : params) { diff --git a/chromium/ui/base/clipboard/clipboard.h b/chromium/ui/base/clipboard/clipboard.h index ff7c04a206a..dd18ad5fe11 100644 --- a/chromium/ui/base/clipboard/clipboard.h +++ b/chromium/ui/base/clipboard/clipboard.h @@ -21,6 +21,7 @@ #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "build/build_config.h" #include "ui/base/clipboard/clipboard_types.h" #include "ui/base/ui_base_export.h" @@ -120,10 +121,6 @@ class UI_BASE_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { return false; } - static ClipboardType FromInt(int32_t type) { - return static_cast<ClipboardType>(type); - } - // Sets the list of threads that are allowed to access the clipboard. static void SetAllowedThreads( const std::vector<base::PlatformThreadId>& allowed_threads); @@ -208,6 +205,13 @@ class UI_BASE_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { virtual void ReadData(const FormatType& format, std::string* result) const = 0; + // Returns an estimate of the time the clipboard was last updated. If the + // time is unknown, returns Time::Time(). + virtual base::Time GetLastModifiedTime() const; + + // Resets the clipboard last modified time to Time::Time(). + virtual void ClearLastModifiedTime(); + // Gets the FormatType corresponding to an arbitrary format string, // registering it with the system if needed. Due to Windows/Linux // limitiations, |format_string| must never be controlled by the user. @@ -334,12 +338,13 @@ class UI_BASE_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { // is done (in the unit test case), but a user (like content) can set which // threads are allowed to call this method. typedef std::vector<base::PlatformThreadId> AllowedThreadsVector; - static base::LazyInstance<AllowedThreadsVector> allowed_threads_; + static base::LazyInstance<AllowedThreadsVector>::DestructorAtExit + allowed_threads_; // Mapping from threads to clipboard objects. typedef std::map<base::PlatformThreadId, std::unique_ptr<Clipboard>> ClipboardMap; - static base::LazyInstance<ClipboardMap> clipboard_map_; + static base::LazyInstance<ClipboardMap>::DestructorAtExit clipboard_map_; // Mutex that controls access to |g_clipboard_map|. static base::LazyInstance<base::Lock>::Leaky clipboard_map_lock_; diff --git a/chromium/ui/base/clipboard/clipboard_android.cc b/chromium/ui/base/clipboard/clipboard_android.cc index 4e175e9a5a4..e97254c493f 100644 --- a/chromium/ui/base/clipboard/clipboard_android.cc +++ b/chromium/ui/base/clipboard/clipboard_android.cc @@ -4,12 +4,18 @@ #include "ui/base/clipboard/clipboard_android.h" +#include <algorithm> +#include <utility> + #include "base/android/context_utils.h" #include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/callback.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 "jni/Clipboard_jni.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" @@ -35,6 +41,7 @@ using base::android::ScopedJavaLocalRef; namespace ui { namespace { + // Various formats we support. const char kURLFormat[] = "url"; const char kPlainTextFormat[] = "text"; @@ -47,28 +54,56 @@ const char kBookmarkFormat[] = "bookmark"; class ClipboardMap { public: ClipboardMap(); + void SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb); std::string Get(const std::string& format); + uint64_t GetSequenceNumber() const; + base::Time GetLastModifiedTime() const; + void ClearLastModifiedTime(); bool HasFormat(const std::string& format); + void OnPrimaryClipboardChanged(); void Set(const std::string& format, const std::string& data); void CommitToAndroidClipboard(); void Clear(); + // Unlike the functions above, does not call |modified_cb_|. + void SetLastModifiedTimeWithoutRunningCallback(base::Time time); + private: + enum class MapState { + kOutOfDate, + kUpToDate, + kPreparingCommit, + }; + + // Updates |last_modified_time_| to |time| and writes it to |local_state_|. + void UpdateLastModifiedTime(base::Time time); + + // Updates |map_| and |map_state_| if necessary by fetching data from Java. void UpdateFromAndroidClipboard(); + std::map<std::string, std::string> map_; + MapState map_state_; base::Lock lock_; + uint64_t sequence_number_; + base::Time last_modified_time_; + + ClipboardAndroid::ModifiedCallback modified_cb_; + // Java class and methods for the Android ClipboardManager. ScopedJavaGlobalRef<jobject> clipboard_manager_; }; base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; -ClipboardMap::ClipboardMap() { - clipboard_manager_.Reset(Java_Clipboard_create( - AttachCurrentThread(), base::android::GetApplicationContext())); +ClipboardMap::ClipboardMap() : map_state_(MapState::kOutOfDate) { + clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread())); DCHECK(clipboard_manager_.obj()); } +void ClipboardMap::SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb) { + modified_cb_ = std::move(cb); +} + std::string ClipboardMap::Get(const std::string& format) { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); @@ -76,15 +111,34 @@ std::string ClipboardMap::Get(const std::string& format) { return it == map_.end() ? std::string() : it->second; } +uint64_t ClipboardMap::GetSequenceNumber() const { + return sequence_number_; +} + +base::Time ClipboardMap::GetLastModifiedTime() const { + return last_modified_time_; +} + +void ClipboardMap::ClearLastModifiedTime() { + UpdateLastModifiedTime(base::Time()); +} + bool ClipboardMap::HasFormat(const std::string& format) { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); return base::ContainsKey(map_, format); } +void ClipboardMap::OnPrimaryClipboardChanged() { + sequence_number_++; + UpdateLastModifiedTime(base::Time::Now()); + map_state_ = MapState::kOutOfDate; +} + void ClipboardMap::Set(const std::string& format, const std::string& data) { base::AutoLock lock(lock_); map_[format] = data; + map_state_ = MapState::kPreparingCommit; } void ClipboardMap::CommitToAndroidClipboard() { @@ -97,21 +151,24 @@ void ClipboardMap::CommitToAndroidClipboard() { return; ScopedJavaLocalRef<jstring> html = - ConvertUTF8ToJavaString(env, map_[kHTMLFormat].c_str()); + ConvertUTF8ToJavaString(env, map_[kHTMLFormat]); ScopedJavaLocalRef<jstring> text = - ConvertUTF8ToJavaString(env, map_[kPlainTextFormat].c_str()); + ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); DCHECK(html.obj() && text.obj()); Java_Clipboard_setHTMLText(env, clipboard_manager_, html, text); } else if (base::ContainsKey(map_, kPlainTextFormat)) { ScopedJavaLocalRef<jstring> str = - ConvertUTF8ToJavaString(env, map_[kPlainTextFormat].c_str()); + ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); DCHECK(str.obj()); Java_Clipboard_setText(env, clipboard_manager_, str); } else { Java_Clipboard_clear(env, clipboard_manager_); NOTIMPLEMENTED(); } + map_state_ = MapState::kUpToDate; + sequence_number_++; + UpdateLastModifiedTime(base::Time::Now()); } void ClipboardMap::Clear() { @@ -119,50 +176,58 @@ void ClipboardMap::Clear() { base::AutoLock lock(lock_); map_.clear(); Java_Clipboard_clear(env, clipboard_manager_); + map_state_ = MapState::kUpToDate; + sequence_number_++; + UpdateLastModifiedTime(base::Time::Now()); +} + +void ClipboardMap::SetLastModifiedTimeWithoutRunningCallback(base::Time time) { + last_modified_time_ = time; } -// Add a key:jstr pair to map, but only if jstr is not null, and also -// not empty. +// Add a key:jstr pair to map, if jstr is null or is empty, then remove that +// entry. void AddMapEntry(JNIEnv* env, std::map<std::string, std::string>* map, const char* key, const ScopedJavaLocalRef<jstring>& jstr) { - if (!jstr.is_null()) { - std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); - if (!str.empty()) - (*map)[key] = str; + if (jstr.is_null()) { + map->erase(key); + return; + } + std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); + if (!str.empty()) { + (*map)[key] = str; + } else { + map->erase(key); } } -// 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::UpdateLastModifiedTime(base::Time time) { + last_modified_time_ = time; + // |modified_callback_| may be null in tests. + if (modified_cb_) + modified_cb_.Run(time); } void ClipboardMap::UpdateFromAndroidClipboard() { - // Fetch the current Android clipboard state. Replace our state with - // the Android state if the Android state has been changed. + DCHECK_NE(MapState::kPreparingCommit, map_state_); + if (map_state_ == MapState::kUpToDate) + return; + + // 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); + AddMapEntry(env, &map_, kPlainTextFormat, jtext); + AddMapEntry(env, &map_, kHTMLFormat, jhtml); - if (!MapIsSubset(android_clipboard_state, map_)) - android_clipboard_state.swap(map_); + map_state_ = MapState::kUpToDate; } } // namespace @@ -264,6 +329,22 @@ Clipboard* Clipboard::Create() { } // ClipboardAndroid implementation. + +void ClipboardAndroid::OnPrimaryClipChanged( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj) { + g_map.Get().OnPrimaryClipboardChanged(); +} + +void ClipboardAndroid::SetModifiedCallback(ModifiedCallback cb) { + g_map.Get().SetModifiedCallback(std::move(cb)); +} + +void ClipboardAndroid::SetLastModifiedTimeWithoutRunningCallback( + base::Time time) { + g_map.Get().SetLastModifiedTimeWithoutRunningCallback(time); +} + ClipboardAndroid::ClipboardAndroid() { DCHECK(CalledOnValidThread()); } @@ -276,10 +357,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, @@ -401,6 +479,16 @@ void ClipboardAndroid::ReadData(const Clipboard::FormatType& format, *result = g_map.Get().Get(format.ToString()); } +base::Time ClipboardAndroid::GetLastModifiedTime() const { + DCHECK(CalledOnValidThread()); + return g_map.Get().GetLastModifiedTime(); +} + +void ClipboardAndroid::ClearLastModifiedTime() { + DCHECK(CalledOnValidThread()); + g_map.Get().ClearLastModifiedTime(); +} + // Main entry point used to write several values in the clipboard. void ClipboardAndroid::WriteObjects(ClipboardType type, const ObjectMap& objects) { @@ -466,4 +554,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 diff --git a/chromium/ui/base/clipboard/clipboard_android.h b/chromium/ui/base/clipboard/clipboard_android.h index b86d275817f..716cc387f74 100644 --- a/chromium/ui/base/clipboard/clipboard_android.h +++ b/chromium/ui/base/clipboard/clipboard_android.h @@ -11,11 +11,31 @@ #include <stddef.h> #include <stdint.h> +#include "base/android/scoped_java_ref.h" +#include "base/callback_forward.h" #include "base/macros.h" +#include "base/time/time.h" namespace ui { class ClipboardAndroid : public Clipboard { + public: + // Callback called whenever the clipboard is modified. The parameter + // represents the time of the modification. + using ModifiedCallback = base::Callback<void(base::Time)>; + + // Called by Java when the Java Clipboard is notified that the clipboard has + // changed. + void OnPrimaryClipChanged(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + + // Sets the callback called whenever the clipboard is modified. + UI_BASE_EXPORT void SetModifiedCallback(ModifiedCallback cb); + + // Sets the last modified time without calling the above callback. + UI_BASE_EXPORT void SetLastModifiedTimeWithoutRunningCallback( + base::Time time); + private: friend class Clipboard; @@ -45,6 +65,8 @@ class ClipboardAndroid : public Clipboard { base::string16* result) const override; void ReadBookmark(base::string16* title, std::string* url) const override; void ReadData(const FormatType& format, std::string* result) const override; + base::Time GetLastModifiedTime() const override; + void ClearLastModifiedTime() override; void WriteObjects(ClipboardType type, const ObjectMap& objects) override; void WriteText(const char* text_data, size_t text_len) override; void WriteHTML(const char* markup_data, @@ -65,6 +87,9 @@ class ClipboardAndroid : public Clipboard { DISALLOW_COPY_AND_ASSIGN(ClipboardAndroid); }; +// Registers the ClipboardAndroid native method. +bool RegisterClipboardAndroid(JNIEnv* env); + } // namespace ui #endif // UI_BASE_CLIPBOARD_CLIPBOARD_ANDROID_H_ diff --git a/chromium/ui/base/clipboard/clipboard_aura.cc b/chromium/ui/base/clipboard/clipboard_aura.cc index 25987ee4ffa..7c02bcba452 100644 --- a/chromium/ui/base/clipboard/clipboard_aura.cc +++ b/chromium/ui/base/clipboard/clipboard_aura.cc @@ -24,6 +24,7 @@ namespace ui { namespace { + const char kMimeTypeFilename[] = "chromium/filename"; const char kMimeTypeBitmap[] = "image/bmp"; const size_t kMaxClipboardSize = 1; @@ -298,10 +299,7 @@ class AuraClipboard { // True if the data on top of the clipboard stack has format |format|. bool HasFormat(AuraClipboardFormat format) const { const ClipboardData* data = GetData(); - if (!data) - return false; - - return data->format() & format; + return data ? data->format() & format : false; } void AddToListEnsuringSize(std::unique_ptr<ClipboardData> data) { @@ -325,28 +323,24 @@ class AuraClipboard { DISALLOW_COPY_AND_ASSIGN(AuraClipboard); }; -AuraClipboard* aura_clipboard = NULL; +AuraClipboard* g_aura_clipboard = NULL; AuraClipboard* GetClipboard() { - if (!aura_clipboard) - aura_clipboard = new AuraClipboard(); - return aura_clipboard; + if (!g_aura_clipboard) + g_aura_clipboard = new AuraClipboard(); + return g_aura_clipboard; } void DeleteClipboard() { - if (aura_clipboard) - delete aura_clipboard; - aura_clipboard = NULL; + delete g_aura_clipboard; + g_aura_clipboard = NULL; } // Helper class to build a ClipboardData object and write it to clipboard. class ClipboardDataBuilder { public: static void CommitToClipboard() { - // Make sure there is always a valid ClipboardData object attached to - // current_data_. - GetCurrentData(); - GetClipboard()->WriteData(std::move(current_data_)); + GetClipboard()->WriteData(TakeCurrentData()); } static void WriteText(const char* text_data, size_t text_len) { @@ -397,14 +391,21 @@ class ClipboardDataBuilder { private: static ClipboardData* GetCurrentData() { if (!current_data_) - current_data_.reset(new ClipboardData); - return current_data_.get(); + current_data_ = new ClipboardData; + return current_data_; } - static std::unique_ptr<ClipboardData> current_data_; + static std::unique_ptr<ClipboardData> TakeCurrentData() { + std::unique_ptr<ClipboardData> data = base::WrapUnique(GetCurrentData()); + current_data_ = nullptr; + return data; + } + // This is a raw pointer instead of a std::unique_ptr to avoid adding a + // static initializer. + static ClipboardData* current_data_; }; -std::unique_ptr<ClipboardData> ClipboardDataBuilder::current_data_; +ClipboardData* ClipboardDataBuilder::current_data_ = nullptr; } // namespace @@ -551,20 +552,16 @@ bool ClipboardAura::IsFormatAvailable(const FormatType& format, if (GetPlainTextFormatType().Equals(format) || GetUrlFormatType().Equals(format)) return clipboard->IsFormatAvailable(TEXT); - else if (GetHtmlFormatType().Equals(format)) + if (GetHtmlFormatType().Equals(format)) return clipboard->IsFormatAvailable(HTML); - else if (GetRtfFormatType().Equals(format)) + if (GetRtfFormatType().Equals(format)) return clipboard->IsFormatAvailable(RTF); - else if (GetBitmapFormatType().Equals(format)) + if (GetBitmapFormatType().Equals(format)) return clipboard->IsFormatAvailable(BITMAP); - else if (GetWebKitSmartPasteFormatType().Equals(format)) + if (GetWebKitSmartPasteFormatType().Equals(format)) return clipboard->IsFormatAvailable(WEB); - else { - const ClipboardData* data = clipboard->GetData(); - if (data && data->custom_data_format() == format.ToString()) - return true; - } - return false; + const ClipboardData* data = clipboard->GetData(); + return data && data->custom_data_format() == format.ToString(); } void ClipboardAura::Clear(ClipboardType type) { |