Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(714)

Side by Side Diff: ui/base/clipboard/clipboard_android.cc

Issue 2832263002: Clipboard Android - Store and Read Last Modified Time from Prefs (Closed)
Patch Set: restore guard Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/android/scoped_java_ref.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/synchronization/lock.h" 15 #include "base/synchronization/lock.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "components/prefs/pref_registry_simple.h"
18 #include "components/prefs/pref_service.h"
17 #include "jni/Clipboard_jni.h" 19 #include "jni/Clipboard_jni.h"
18 #include "third_party/skia/include/core/SkBitmap.h" 20 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/gfx/geometry/size.h" 21 #include "ui/gfx/geometry/size.h"
20 22
21 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, 23 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML,
22 // HTML+text now that Android's clipboard system supports them, then nuke the 24 // HTML+text now that Android's clipboard system supports them, then nuke the
23 // legacy implementation note below. 25 // legacy implementation note below.
24 26
25 // Legacy implementation note: 27 // Legacy implementation note:
26 // The Android clipboard system used to only support text format. So we used the 28 // The Android clipboard system used to only support text format. So we used the
27 // Android system when some text was added or retrieved from the system. For 29 // Android system when some text was added or retrieved from the system. For
28 // anything else, we STILL store the value in some process wide static 30 // anything else, we STILL store the value in some process wide static
29 // variable protected by a lock. So the (non-text) clipboard will only work 31 // variable protected by a lock. So the (non-text) clipboard will only work
30 // within the same process. 32 // within the same process.
31 33
32 using base::android::AttachCurrentThread; 34 using base::android::AttachCurrentThread;
33 using base::android::ClearException; 35 using base::android::ClearException;
34 using base::android::ConvertJavaStringToUTF8; 36 using base::android::ConvertJavaStringToUTF8;
35 using base::android::ConvertUTF8ToJavaString; 37 using base::android::ConvertUTF8ToJavaString;
36 using base::android::ScopedJavaGlobalRef; 38 using base::android::ScopedJavaGlobalRef;
37 using base::android::ScopedJavaLocalRef; 39 using base::android::ScopedJavaLocalRef;
38 40
39 namespace ui { 41 namespace ui {
40 42
41 namespace { 43 namespace {
42 44
45 // Stores the last modified time in Time::Time's internal format (int64) as
46 // a pref in local store. (I.e., this is not a per-profile pref.)
47 const char kClipboardLastModifiedTimePref[] = "ui.clipboard.last_modified_time";
48
43 // Various formats we support. 49 // Various formats we support.
44 const char kURLFormat[] = "url"; 50 const char kURLFormat[] = "url";
45 const char kPlainTextFormat[] = "text"; 51 const char kPlainTextFormat[] = "text";
46 const char kHTMLFormat[] = "html"; 52 const char kHTMLFormat[] = "html";
47 const char kRTFFormat[] = "rtf"; 53 const char kRTFFormat[] = "rtf";
48 const char kBitmapFormat[] = "bitmap"; 54 const char kBitmapFormat[] = "bitmap";
49 const char kWebKitSmartPasteFormat[] = "webkit_smart"; 55 const char kWebKitSmartPasteFormat[] = "webkit_smart";
50 const char kBookmarkFormat[] = "bookmark"; 56 const char kBookmarkFormat[] = "bookmark";
51 57
52 class ClipboardMap { 58 class ClipboardMap {
53 public: 59 public:
54 ClipboardMap(); 60 ClipboardMap();
61 void SetLocalState(PrefService* local_state);
55 std::string Get(const std::string& format); 62 std::string Get(const std::string& format);
56 uint64_t GetSequenceNumber() const; 63 uint64_t GetSequenceNumber() const;
57 base::Time GetLastModifiedTime() const; 64 base::Time GetLastModifiedTime() const;
58 void ClearLastModifiedTime(); 65 void ClearLastModifiedTime();
59 bool HasFormat(const std::string& format); 66 bool HasFormat(const std::string& format);
60 void OnPrimaryClipboardChanged(); 67 void OnPrimaryClipboardChanged();
61 void Set(const std::string& format, const std::string& data); 68 void Set(const std::string& format, const std::string& data);
62 void CommitToAndroidClipboard(); 69 void CommitToAndroidClipboard();
63 void Clear(); 70 void Clear();
64 71
65 private: 72 private:
66 enum class MapState { 73 enum class MapState {
67 kOutOfDate, 74 kOutOfDate,
68 kUpToDate, 75 kUpToDate,
69 kPreparingCommit, 76 kPreparingCommit,
70 }; 77 };
71 78
79 // Writes |last_modified_time_| to |local_state_|.
80 void UpdateLastModifiedTimePref();
81
82 // Updates |map_| and |map_state_| if necessary by fetching data from Java.
72 void UpdateFromAndroidClipboard(); 83 void UpdateFromAndroidClipboard();
84
73 std::map<std::string, std::string> map_; 85 std::map<std::string, std::string> map_;
74 MapState map_state_; 86 MapState map_state_;
75 base::Lock lock_; 87 base::Lock lock_;
76 88
77 uint64_t sequence_number_; 89 uint64_t sequence_number_;
78 base::Time last_modified_time_; 90 base::Time last_modified_time_;
79 91
92 PrefService* local_state_;
93
80 // Java class and methods for the Android ClipboardManager. 94 // Java class and methods for the Android ClipboardManager.
81 ScopedJavaGlobalRef<jobject> clipboard_manager_; 95 ScopedJavaGlobalRef<jobject> clipboard_manager_;
82 }; 96 };
83 base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER; 97 base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER;
84 98
85 ClipboardMap::ClipboardMap() : map_state_(MapState::kOutOfDate) { 99 ClipboardMap::ClipboardMap() : map_state_(MapState::kOutOfDate) {
86 clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread())); 100 clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread()));
87 DCHECK(clipboard_manager_.obj()); 101 DCHECK(clipboard_manager_.obj());
88 } 102 }
89 103
104 void ClipboardMap::SetLocalState(PrefService* local_state) {
105 local_state_ = local_state;
106 last_modified_time_ = base::Time::FromInternalValue(
107 local_state_->GetInt64(kClipboardLastModifiedTimePref));
108 }
109
90 std::string ClipboardMap::Get(const std::string& format) { 110 std::string ClipboardMap::Get(const std::string& format) {
91 base::AutoLock lock(lock_); 111 base::AutoLock lock(lock_);
92 UpdateFromAndroidClipboard(); 112 UpdateFromAndroidClipboard();
93 std::map<std::string, std::string>::const_iterator it = map_.find(format); 113 std::map<std::string, std::string>::const_iterator it = map_.find(format);
94 return it == map_.end() ? std::string() : it->second; 114 return it == map_.end() ? std::string() : it->second;
95 } 115 }
96 116
97 uint64_t ClipboardMap::GetSequenceNumber() const { 117 uint64_t ClipboardMap::GetSequenceNumber() const {
98 return sequence_number_; 118 return sequence_number_;
99 } 119 }
100 120
101 base::Time ClipboardMap::GetLastModifiedTime() const { 121 base::Time ClipboardMap::GetLastModifiedTime() const {
102 return last_modified_time_; 122 return last_modified_time_;
103 } 123 }
104 124
105 void ClipboardMap::ClearLastModifiedTime() { 125 void ClipboardMap::ClearLastModifiedTime() {
106 last_modified_time_ = base::Time(); 126 last_modified_time_ = base::Time();
127 UpdateLastModifiedTimePref();
107 } 128 }
108 129
109 bool ClipboardMap::HasFormat(const std::string& format) { 130 bool ClipboardMap::HasFormat(const std::string& format) {
110 base::AutoLock lock(lock_); 131 base::AutoLock lock(lock_);
111 UpdateFromAndroidClipboard(); 132 UpdateFromAndroidClipboard();
112 return base::ContainsKey(map_, format); 133 return base::ContainsKey(map_, format);
113 } 134 }
114 135
115 void ClipboardMap::OnPrimaryClipboardChanged() { 136 void ClipboardMap::OnPrimaryClipboardChanged() {
116 sequence_number_++; 137 sequence_number_++;
117 last_modified_time_ = base::Time::Now(); 138 last_modified_time_ = base::Time::Now();
139 UpdateLastModifiedTimePref();
118 map_state_ = MapState::kOutOfDate; 140 map_state_ = MapState::kOutOfDate;
119 } 141 }
120 142
121 void ClipboardMap::Set(const std::string& format, const std::string& data) { 143 void ClipboardMap::Set(const std::string& format, const std::string& data) {
122 base::AutoLock lock(lock_); 144 base::AutoLock lock(lock_);
123 map_[format] = data; 145 map_[format] = data;
124 map_state_ = MapState::kPreparingCommit; 146 map_state_ = MapState::kPreparingCommit;
125 } 147 }
126 148
127 void ClipboardMap::CommitToAndroidClipboard() { 149 void ClipboardMap::CommitToAndroidClipboard() {
(...skipping 17 matching lines...) Expand all
145 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); 167 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]);
146 DCHECK(str.obj()); 168 DCHECK(str.obj());
147 Java_Clipboard_setText(env, clipboard_manager_, str); 169 Java_Clipboard_setText(env, clipboard_manager_, str);
148 } else { 170 } else {
149 Java_Clipboard_clear(env, clipboard_manager_); 171 Java_Clipboard_clear(env, clipboard_manager_);
150 NOTIMPLEMENTED(); 172 NOTIMPLEMENTED();
151 } 173 }
152 map_state_ = MapState::kUpToDate; 174 map_state_ = MapState::kUpToDate;
153 sequence_number_++; 175 sequence_number_++;
154 last_modified_time_ = base::Time::Now(); 176 last_modified_time_ = base::Time::Now();
177 UpdateLastModifiedTimePref();
155 } 178 }
156 179
157 void ClipboardMap::Clear() { 180 void ClipboardMap::Clear() {
158 JNIEnv* env = AttachCurrentThread(); 181 JNIEnv* env = AttachCurrentThread();
159 base::AutoLock lock(lock_); 182 base::AutoLock lock(lock_);
160 map_.clear(); 183 map_.clear();
161 Java_Clipboard_clear(env, clipboard_manager_); 184 Java_Clipboard_clear(env, clipboard_manager_);
162 map_state_ = MapState::kUpToDate; 185 map_state_ = MapState::kUpToDate;
163 sequence_number_++; 186 sequence_number_++;
164 last_modified_time_ = base::Time::Now(); 187 last_modified_time_ = base::Time::Now();
188 UpdateLastModifiedTimePref();
Ted C 2017/04/24 20:45:48 should we make UpdateLastModifiedTimePref take the
Mark P 2017/04/24 22:19:56 Makes sense to me. Done.
165 } 189 }
166 190
167 // Add a key:jstr pair to map, but only if jstr is not null, and also 191 // Add a key:jstr pair to map, but only if jstr is not null, and also
168 // not empty. 192 // not empty.
169 void AddMapEntry(JNIEnv* env, 193 void AddMapEntry(JNIEnv* env,
170 std::map<std::string, std::string>* map, 194 std::map<std::string, std::string>* map,
171 const char* key, 195 const char* key,
172 const ScopedJavaLocalRef<jstring>& jstr) { 196 const ScopedJavaLocalRef<jstring>& jstr) {
173 if (!jstr.is_null()) { 197 if (!jstr.is_null()) {
174 std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); 198 std::string str = ConvertJavaStringToUTF8(env, jstr.obj());
175 if (!str.empty()) 199 if (!str.empty())
176 (*map)[key] = str; 200 (*map)[key] = str;
177 } 201 }
178 } 202 }
179 203
204 void ClipboardMap::UpdateLastModifiedTimePref() {
205 // |local_state_| may be null in tests.
206 if (local_state_) {
207 local_state_->SetInt64(kClipboardLastModifiedTimePref,
208 last_modified_time_.ToInternalValue());
209 }
210 }
211
180 void ClipboardMap::UpdateFromAndroidClipboard() { 212 void ClipboardMap::UpdateFromAndroidClipboard() {
181 DCHECK_NE(MapState::kPreparingCommit, map_state_); 213 DCHECK_NE(MapState::kPreparingCommit, map_state_);
182 if (map_state_ == MapState::kUpToDate) 214 if (map_state_ == MapState::kUpToDate)
183 return; 215 return;
184 216
185 // Fetch the current Android clipboard state. 217 // Fetch the current Android clipboard state.
186 lock_.AssertAcquired(); 218 lock_.AssertAcquired();
187 JNIEnv* env = AttachCurrentThread(); 219 JNIEnv* env = AttachCurrentThread();
188 220
189 ScopedJavaLocalRef<jstring> jtext = 221 ScopedJavaLocalRef<jstring> jtext =
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 322 }
291 323
292 // Clipboard factory method. 324 // Clipboard factory method.
293 // static 325 // static
294 Clipboard* Clipboard::Create() { 326 Clipboard* Clipboard::Create() {
295 return new ClipboardAndroid; 327 return new ClipboardAndroid;
296 } 328 }
297 329
298 // ClipboardAndroid implementation. 330 // ClipboardAndroid implementation.
299 331
332 // static
333 void ClipboardAndroid::RegisterPrefs(PrefRegistrySimple* registry) {
334 registry->RegisterInt64Pref(kClipboardLastModifiedTimePref, 0u);
335 }
336
337 void ClipboardAndroid::SetLocalState(PrefService* local_state) {
338 g_map.Get().SetLocalState(local_state);
339 }
340
300 void ClipboardAndroid::OnPrimaryClipChanged( 341 void ClipboardAndroid::OnPrimaryClipChanged(
301 JNIEnv* env, 342 JNIEnv* env,
302 const base::android::JavaParamRef<jobject>& obj) { 343 const base::android::JavaParamRef<jobject>& obj) {
303 g_map.Get().OnPrimaryClipboardChanged(); 344 g_map.Get().OnPrimaryClipboardChanged();
304 } 345 }
305 346
306 ClipboardAndroid::ClipboardAndroid() { 347 ClipboardAndroid::ClipboardAndroid() {
307 DCHECK(CalledOnValidThread()); 348 DCHECK(CalledOnValidThread());
308 } 349 }
309 350
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 return RegisterNativesImpl(env); 557 return RegisterNativesImpl(env);
517 } 558 }
518 559
519 // Returns a pointer to the current ClipboardAndroid object. 560 // Returns a pointer to the current ClipboardAndroid object.
520 static jlong Init(JNIEnv* env, 561 static jlong Init(JNIEnv* env,
521 const base::android::JavaParamRef<jobject>& obj) { 562 const base::android::JavaParamRef<jobject>& obj) {
522 return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread()); 563 return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread());
523 } 564 }
524 565
525 } // namespace ui 566 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698