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

Side by Side Diff: components/enhanced_bookmarks/bookmark_server_cluster_service.cc

Issue 539173004: Bring up of the enhanced bookmarks cluster service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@intermediary2
Patch Set: battre@ feedback. Created 6 years, 2 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
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/enhanced_bookmarks/bookmark_server_cluster_service.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/values.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
14 #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h"
15 #include "components/enhanced_bookmarks/pref_names.h"
16 #include "components/enhanced_bookmarks/proto/cluster.pb.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "components/signin/core/browser/signin_manager.h"
19 #include "net/base/url_util.h"
20 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_request_context_getter.h"
22
23 namespace {
24 const std::string kClusterUrl("https://www.google.com/stars/cluster");
25 const int kPrefServiceVersion = 1;
26 const char* kPrefServiceVersionKey = "version";
27 const char* kPrefServiceDataKey = "data";
28 const char* kAuthIdKey = "auth_id";
29 } // namespace
30
31 namespace enhanced_bookmarks {
32
33 BookmarkServerClusterService::BookmarkServerClusterService(
34 const std::string& application_language_code,
35 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
36 ProfileOAuth2TokenService* token_service,
37 SigninManagerBase* signin_manager,
38 enhanced_bookmarks::EnhancedBookmarkModel* enhanced_bookmark_model,
39 PrefService* pref_service)
40 : BookmarkServerService(request_context_getter,
41 token_service,
42 signin_manager,
43 enhanced_bookmark_model),
44 application_language_code_(application_language_code),
45 pref_service_(pref_service) {
46 LoadModel();
47
48 if (model_->loaded())
49 TriggerTokenRequest(false);
50
51 GetSigninManager()->AddObserver(this);
52 }
53
54 BookmarkServerClusterService::~BookmarkServerClusterService() {
55 GetSigninManager()->RemoveObserver(this);
56 }
57
58 const std::vector<const BookmarkNode*>
59 BookmarkServerClusterService::BookmarksForClusterNamed(
60 const std::string& cluster_name) const {
61 std::vector<const BookmarkNode*> results;
62
63 ClusterMap::const_iterator cluster_it = cluster_data_.find(cluster_name);
64 if (cluster_it == cluster_data_.end())
65 return results;
66
67 for (auto& star_id : cluster_it->second) {
68 const BookmarkNode* bookmark = BookmarkForRemoteId(star_id);
69 if (bookmark)
70 results.push_back(bookmark);
71 }
72 return results;
73 }
74
75 const std::vector<std::string>
76 BookmarkServerClusterService::ClustersForBookmark(
77 const BookmarkNode* bookmark) const {
78 const std::string& star_id = RemoteIDForBookmark(bookmark);
79
80 // TODO(noyau): if this turns out to be a perf bottleneck this may be improved
81 // by storing a reverse map from id to cluster.
82 std::vector<std::string> clusters;
83 for (auto& pair : cluster_data_) {
84 const std::vector<std::string>& stars_ids = pair.second;
85 if (std::find(stars_ids.begin(), stars_ids.end(), star_id) !=
86 stars_ids.end())
87 clusters.push_back(pair.first);
88 }
89 return clusters;
90 }
91
92 const std::vector<std::string> BookmarkServerClusterService::GetClusters()
93 const {
94 std::vector<std::string> cluster_names;
95
96 for (auto& pair : cluster_data_) {
97 cluster_names.push_back(pair.first);
98 }
battre 2014/10/07 16:09:43 Nit: remove {}?
noyau (Ping after 24h) 2014/10/07 16:28:39 Done.
99
100 return cluster_names;
101 }
102
103 void BookmarkServerClusterService::RegisterPrefs(
104 user_prefs::PrefRegistrySyncable* registry) {
105 registry->RegisterDictionaryPref(
106 prefs::kBookmarkClusters,
107 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
108 }
109
110 scoped_ptr<net::URLFetcher> BookmarkServerClusterService::CreateFetcher() {
111 // Add the necessary arguments to the URI.
112 GURL url(kClusterUrl);
113 url = net::AppendQueryParameter(url, "output", "proto");
114
115 // Append language.
116 if (!application_language_code_.empty())
117 url = net::AppendQueryParameter(url, "hl", application_language_code_);
118
119 url = net::AppendQueryParameter(url, "v", model_->GetVersionString());
120
121 // Build the URLFetcher to perform the request.
122 scoped_ptr<net::URLFetcher> url_fetcher(
123 net::URLFetcher::Create(url, net::URLFetcher::POST, this));
124
125 // Binary encode a basic request proto.
126 image_collections::ClusterRequest request_proto;
127 request_proto.set_cluster_all(true);
128
129 std::string proto_output;
130 bool result = request_proto.SerializePartialToString(&proto_output);
131 DCHECK(result);
132
133 url_fetcher->SetUploadData("application/octet-stream", proto_output);
134 return url_fetcher;
135 }
136
137 bool BookmarkServerClusterService::ProcessResponse(const std::string& response,
138 bool* should_notify) {
139 DCHECK(*should_notify);
140 image_collections::ClusterResponse response_proto;
141 bool result = response_proto.ParseFromString(response);
142 if (!result)
143 return false; // Not formatted properly.
144
145 ClusterMap new_cluster_data;
146 for (const auto& cluster : response_proto.clusters()) {
147 const std::string& title = cluster.title();
148 if (title.empty())
149 continue;
150 std::vector<std::string> stars_ids;
151 for (auto& doc : cluster.docs()) {
152 if (!doc.empty())
153 stars_ids.push_back(doc);
154 }
155 if (stars_ids.size())
156 new_cluster_data[title] = stars_ids;
157 }
158
159 if (new_cluster_data.size() == cluster_data_.size() &&
160 std::equal(new_cluster_data.begin(),
161 new_cluster_data.end(),
162 cluster_data_.begin())) {
163 *should_notify = false;
164 } else {
165 SwapModel(&new_cluster_data);
166 }
167 return true;
168 }
169
170 void BookmarkServerClusterService::CleanAfterFailure() {
171 if (cluster_data_.empty())
172 return;
173
174 ClusterMap empty;
175 SwapModel(&empty);
176 }
177
178 void BookmarkServerClusterService::EnhancedBookmarkModelLoaded() {
179 TriggerTokenRequest(false);
180 }
181
182 void BookmarkServerClusterService::EnhancedBookmarkAdded(
183 const BookmarkNode* node) {
184 // Nothing to do.
185 }
186
187 void BookmarkServerClusterService::EnhancedBookmarkRemoved(
188 const BookmarkNode* node) {
189 // It is possible to remove the entries from the map here, but as those are
190 // filtered in ClustersForBookmark() this is not strictly necessary.
191 }
192
193 void BookmarkServerClusterService::EnhancedBookmarkAllUserNodesRemoved() {
194 if (!cluster_data_.empty()) {
195 ClusterMap empty;
196 SwapModel(&empty);
197 }
198 }
199
200 void BookmarkServerClusterService::EnhancedBookmarkRemoteIdChanged(
201 const BookmarkNode* node,
202 const std::string& old_remote_id,
203 const std::string& remote_id) {
204 std::vector<std::string> clusters;
205 for (auto& pair : cluster_data_) {
206 std::vector<std::string>& stars_ids = pair.second;
207 std::replace(stars_ids.begin(), stars_ids.end(), old_remote_id, remote_id);
208 }
209 }
210
211 void BookmarkServerClusterService::GoogleSignedOut(
212 const std::string& account_id,
213 const std::string& username) {
214 if (!cluster_data_.empty()) {
215 ClusterMap empty;
216 SwapModel(&empty);
217 }
218 }
219
220 void BookmarkServerClusterService::SwapModel(ClusterMap* cluster_map) {
221 cluster_data_.swap(*cluster_map);
222 const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
223 scoped_ptr<base::DictionaryValue> dictionary(
224 Serialize(cluster_data_, auth_id));
225 pref_service_->Set(prefs::kBookmarkClusters, *dictionary);
226 }
227
228 void BookmarkServerClusterService::LoadModel() {
229 const base::DictionaryValue* dictionary =
230 pref_service_->GetDictionary(prefs::kBookmarkClusters);
231 const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
232
233 ClusterMap loaded_data;
234 bool result = BookmarkServerClusterService::Deserialize(
235 *dictionary, auth_id, &loaded_data);
236 if (result)
237 cluster_data_.swap(loaded_data);
238 }
239
240 //
241 // Serialization.
242 //
battre 2014/10/07 16:09:43 // static
noyau (Ping after 24h) 2014/10/07 16:28:39 Done (x3)
243 scoped_ptr<base::DictionaryValue> BookmarkServerClusterService::Serialize(
244 const ClusterMap& cluster_map,
245 const std::string& auth_id) {
246 // Create a list of all clusters. For each cluster, make another list. The
247 // first element in the list is the key (cluster name). All subsequent
248 // elements are stars ids.
249 scoped_ptr<base::ListValue> all_clusters(new base::ListValue);
250 for (auto& pair : cluster_map) {
251 scoped_ptr<base::ListValue> cluster(new base::ListValue);
252 cluster->AppendString(pair.first);
253 cluster->AppendStrings(pair.second);
254 all_clusters->Append(cluster.release());
255 }
256
257 // The dictionary that will be serialized has two fields: a version field and
258 // a data field.
259 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue);
260 data->SetInteger(kPrefServiceVersionKey, kPrefServiceVersion);
261 data->Set(kPrefServiceDataKey, all_clusters.release());
262 data->SetString(kAuthIdKey, auth_id);
263
264 return data.Pass();
265 }
266
battre 2014/10/07 16:09:43 // static
noyau (Ping after 24h) 2014/10/07 16:28:39 Done.
267 bool BookmarkServerClusterService::Deserialize(
268 const base::DictionaryValue& value,
269 const std::string& auth_id,
270 ClusterMap* out_map) {
271 ClusterMap output;
272
273 // Check version.
274 int version;
275 if (!value.GetInteger(kPrefServiceVersionKey, &version))
276 return false;
277 if (version != kPrefServiceVersion)
278 return false;
279
280 // Check auth id.
281 std::string id;
282 if (!value.GetString(kAuthIdKey, &id))
283 return false;
284 if (id != auth_id)
285 return false;
286
287 const base::ListValue* all_clusters = NULL;
288 if (!value.GetList(kPrefServiceDataKey, &all_clusters))
289 return false;
290
291 for (size_t index = 0; index < all_clusters->GetSize(); ++index) {
292 const base::ListValue* cluster = NULL;
293 if (!all_clusters->GetList(index, &cluster))
294 return false;
295 if (cluster->GetSize() < 1)
296 return false;
297 std::string key;
298 if (!cluster->GetString(0, &key))
299 return false;
300 std::vector<std::string> stars_ids;
301 for (size_t index = 1; index < cluster->GetSize(); ++index) {
302 std::string stars_id;
303 if (!cluster->GetString(index, &stars_id))
304 return false;
305 stars_ids.push_back(stars_id);
306 }
307 output.insert(std::make_pair(key, stars_ids));
308 }
309 out_map->swap(output);
310 return true;
311 }
312
313 } // namespace enhanced_bookmarks
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698