summaryrefslogtreecommitdiff
path: root/chromium/ui/base/clipboard
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-12 14:07:37 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-17 10:29:26 +0000
commitec02ee4181c49b61fce1c8fb99292dbb8139cc90 (patch)
tree25cde714b2b71eb639d1cd53f5a22e9ba76e14ef /chromium/ui/base/clipboard
parentbb09965444b5bb20b096a291445170876225268d (diff)
downloadqtwebengine-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.cc12
-rw-r--r--chromium/ui/base/clipboard/clipboard.h17
-rw-r--r--chromium/ui/base/clipboard/clipboard_android.cc164
-rw-r--r--chromium/ui/base/clipboard/clipboard_android.h25
-rw-r--r--chromium/ui/base/clipboard/clipboard_aura.cc55
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) {