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

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: revert omnibox_field_trial_code, rebase 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
Bernhard Bauer 2017/04/25 13:30:06 base::Time?
Mark P 2017/04/25 18:51:21 Correct. Done.
46 // a pref in local store. (I.e., this is not a per-profile pref.)
Bernhard Bauer 2017/04/25 13:30:06 Again, also kind of a layering violation, but I gu
Mark P 2017/04/25 18:51:21 Acknowledged.
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 // Updates |last_modified_time_| to |time| and writes it to |local_state_|.
80 void UpdateLastModifiedTime(const base::Time& time);
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 UpdateLastModifiedTime(base::Time());
107 } 127 }
108 128
109 bool ClipboardMap::HasFormat(const std::string& format) { 129 bool ClipboardMap::HasFormat(const std::string& format) {
110 base::AutoLock lock(lock_); 130 base::AutoLock lock(lock_);
111 UpdateFromAndroidClipboard(); 131 UpdateFromAndroidClipboard();
112 return base::ContainsKey(map_, format); 132 return base::ContainsKey(map_, format);
113 } 133 }
114 134
115 void ClipboardMap::OnPrimaryClipboardChanged() { 135 void ClipboardMap::OnPrimaryClipboardChanged() {
116 sequence_number_++; 136 sequence_number_++;
117 last_modified_time_ = base::Time::Now(); 137 UpdateLastModifiedTime(base::Time::Now());
118 map_state_ = MapState::kOutOfDate; 138 map_state_ = MapState::kOutOfDate;
119 } 139 }
120 140
121 void ClipboardMap::Set(const std::string& format, const std::string& data) { 141 void ClipboardMap::Set(const std::string& format, const std::string& data) {
122 base::AutoLock lock(lock_); 142 base::AutoLock lock(lock_);
123 map_[format] = data; 143 map_[format] = data;
124 map_state_ = MapState::kPreparingCommit; 144 map_state_ = MapState::kPreparingCommit;
125 } 145 }
126 146
127 void ClipboardMap::CommitToAndroidClipboard() { 147 void ClipboardMap::CommitToAndroidClipboard() {
(...skipping 16 matching lines...) Expand all
144 ScopedJavaLocalRef<jstring> str = 164 ScopedJavaLocalRef<jstring> str =
145 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]); 165 ConvertUTF8ToJavaString(env, map_[kPlainTextFormat]);
146 DCHECK(str.obj()); 166 DCHECK(str.obj());
147 Java_Clipboard_setText(env, clipboard_manager_, str); 167 Java_Clipboard_setText(env, clipboard_manager_, str);
148 } else { 168 } else {
149 Java_Clipboard_clear(env, clipboard_manager_); 169 Java_Clipboard_clear(env, clipboard_manager_);
150 NOTIMPLEMENTED(); 170 NOTIMPLEMENTED();
151 } 171 }
152 map_state_ = MapState::kUpToDate; 172 map_state_ = MapState::kUpToDate;
153 sequence_number_++; 173 sequence_number_++;
154 last_modified_time_ = base::Time::Now(); 174 UpdateLastModifiedTime(base::Time::Now());
155 } 175 }
156 176
157 void ClipboardMap::Clear() { 177 void ClipboardMap::Clear() {
158 JNIEnv* env = AttachCurrentThread(); 178 JNIEnv* env = AttachCurrentThread();
159 base::AutoLock lock(lock_); 179 base::AutoLock lock(lock_);
160 map_.clear(); 180 map_.clear();
161 Java_Clipboard_clear(env, clipboard_manager_); 181 Java_Clipboard_clear(env, clipboard_manager_);
162 map_state_ = MapState::kUpToDate; 182 map_state_ = MapState::kUpToDate;
163 sequence_number_++; 183 sequence_number_++;
164 last_modified_time_ = base::Time::Now(); 184 UpdateLastModifiedTime(base::Time::Now());
165 } 185 }
166 186
167 // Add a key:jstr pair to map, but only if jstr is not null, and also 187 // Add a key:jstr pair to map, but only if jstr is not null, and also
168 // not empty. 188 // not empty.
169 void AddMapEntry(JNIEnv* env, 189 void AddMapEntry(JNIEnv* env,
170 std::map<std::string, std::string>* map, 190 std::map<std::string, std::string>* map,
171 const char* key, 191 const char* key,
172 const ScopedJavaLocalRef<jstring>& jstr) { 192 const ScopedJavaLocalRef<jstring>& jstr) {
173 if (!jstr.is_null()) { 193 if (!jstr.is_null()) {
174 std::string str = ConvertJavaStringToUTF8(env, jstr.obj()); 194 std::string str = ConvertJavaStringToUTF8(env, jstr.obj());
175 if (!str.empty()) 195 if (!str.empty())
176 (*map)[key] = str; 196 (*map)[key] = str;
177 } 197 }
178 } 198 }
179 199
200 void ClipboardMap::UpdateLastModifiedTime(const base::Time& time) {
dcheng 2017/04/25 13:17:12 base::Time is designed to be efficiently passed by
Mark P 2017/04/25 18:51:21 Done.
201 last_modified_time_ = time;
202 // |local_state_| may be null in tests.
203 if (local_state_) {
204 local_state_->SetInt64(kClipboardLastModifiedTimePref,
205 last_modified_time_.ToInternalValue());
206 }
207 }
208
180 void ClipboardMap::UpdateFromAndroidClipboard() { 209 void ClipboardMap::UpdateFromAndroidClipboard() {
181 DCHECK_NE(MapState::kPreparingCommit, map_state_); 210 DCHECK_NE(MapState::kPreparingCommit, map_state_);
182 if (map_state_ == MapState::kUpToDate) 211 if (map_state_ == MapState::kUpToDate)
183 return; 212 return;
184 213
185 // Fetch the current Android clipboard state. 214 // Fetch the current Android clipboard state.
186 lock_.AssertAcquired(); 215 lock_.AssertAcquired();
187 JNIEnv* env = AttachCurrentThread(); 216 JNIEnv* env = AttachCurrentThread();
188 217
189 ScopedJavaLocalRef<jstring> jtext = 218 ScopedJavaLocalRef<jstring> jtext =
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 319 }
291 320
292 // Clipboard factory method. 321 // Clipboard factory method.
293 // static 322 // static
294 Clipboard* Clipboard::Create() { 323 Clipboard* Clipboard::Create() {
295 return new ClipboardAndroid; 324 return new ClipboardAndroid;
296 } 325 }
297 326
298 // ClipboardAndroid implementation. 327 // ClipboardAndroid implementation.
299 328
329 // static
330 void ClipboardAndroid::RegisterPrefs(PrefRegistrySimple* registry) {
331 registry->RegisterInt64Pref(kClipboardLastModifiedTimePref, 0u);
332 }
333
334 void ClipboardAndroid::SetLocalState(PrefService* local_state) {
335 g_map.Get().SetLocalState(local_state);
336 }
337
300 void ClipboardAndroid::OnPrimaryClipChanged( 338 void ClipboardAndroid::OnPrimaryClipChanged(
301 JNIEnv* env, 339 JNIEnv* env,
302 const base::android::JavaParamRef<jobject>& obj) { 340 const base::android::JavaParamRef<jobject>& obj) {
303 g_map.Get().OnPrimaryClipboardChanged(); 341 g_map.Get().OnPrimaryClipboardChanged();
304 } 342 }
305 343
306 ClipboardAndroid::ClipboardAndroid() { 344 ClipboardAndroid::ClipboardAndroid() {
307 DCHECK(CalledOnValidThread()); 345 DCHECK(CalledOnValidThread());
308 } 346 }
309 347
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 return RegisterNativesImpl(env); 551 return RegisterNativesImpl(env);
514 } 552 }
515 553
516 // Returns a pointer to the current ClipboardAndroid object. 554 // Returns a pointer to the current ClipboardAndroid object.
517 static jlong Init(JNIEnv* env, 555 static jlong Init(JNIEnv* env,
518 const base::android::JavaParamRef<jobject>& obj) { 556 const base::android::JavaParamRef<jobject>& obj) {
519 return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread()); 557 return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread());
520 } 558 }
521 559
522 } // namespace ui 560 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698