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

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: Rebase, OVERRIDE->override, plus better comments. 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 (std::vector<std::string>::const_iterator it = cluster_it->second.begin();
68 it != cluster_it->second.end();
69 ++it) {
70 const std::string& star_id = *it;
battre 2014/10/07 13:39:29 nit/opt: you can use C++11 syntax now http://chrom
noyau (Ping after 24h) 2014/10/07 15:19:32 Arrrgh! DOne another pass reverting the changes to
71 const BookmarkNode* bookmark = BookmarkForRemoteId(star_id);
72 if (bookmark)
73 results.push_back(bookmark);
74 }
75 return results;
76 }
77
78 const std::vector<std::string>
79 BookmarkServerClusterService::ClustersForBookmark(
80 const BookmarkNode* bookmark) const {
81 const std::string& star_id = RemoteIDForBookmark(bookmark);
82
83 // TODO(noyau): if this turns out to be a perf bottleneck this may be improved
84 // by storing a reverse map from id to cluster.
85 std::vector<std::string> clusters;
86 for (ClusterMap::const_iterator it = cluster_data_.begin();
87 it != cluster_data_.end();
88 ++it) {
89 const std::vector<std::string>& v = it->second;
battre 2014/10/07 13:39:28 nit/opt: rename v to stars_ids?
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
90 if (std::find(v.begin(), v.end(), star_id) != v.end())
91 clusters.push_back(it->first);
92 }
93 return clusters;
94 }
95
96 const std::vector<std::string> BookmarkServerClusterService::GetClusters()
97 const {
98 std::vector<std::string> cluster_names;
99
100 for (ClusterMap::const_iterator it = cluster_data_.begin();
101 it != cluster_data_.end();
102 ++it) {
103 cluster_names.push_back(it->first);
104 }
105
106 return cluster_names;
107 }
108
109 void BookmarkServerClusterService::RegisterPrefs(
110 user_prefs::PrefRegistrySyncable* registry) {
111 registry->RegisterDictionaryPref(
112 prefs::kBookmarkClusters,
113 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
114 }
115
116 net::URLFetcher* BookmarkServerClusterService::CreateFetcher() {
battre 2014/10/07 13:39:28 scoped_ptr<net::URLFetcher>?
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
117 // Add the necessary arguments to the URI.
118 GURL url(kClusterUrl);
119 url = net::AppendQueryParameter(url, "output", "proto");
120
121 // Append language.
122 if (!application_language_code_.empty())
123 url = net::AppendQueryParameter(url, "hl", application_language_code_);
124
125 url = net::AppendQueryParameter(url, "v", model_->GetVersionString());
126
127 // Build the URLFetcher to perform the request.
128 net::URLFetcher* url_fetcher =
129 net::URLFetcher::Create(url, net::URLFetcher::POST, this);
130
131 // Binary encode a basic request proto.
132 image_collections::ClusterRequest request_proto;
133 request_proto.set_cluster_all(true);
134
135 std::string proto_output;
136 bool result = request_proto.SerializePartialToString(&proto_output);
137 DCHECK(result);
138
139 url_fetcher->SetUploadData("application/octet-stream", proto_output);
140 return url_fetcher;
141 }
142
143 bool BookmarkServerClusterService::ProcessResponse(const std::string& response,
144 bool* should_notify) {
145 DCHECK(*should_notify);
146 image_collections::ClusterResponse response_proto;
147 bool result = response_proto.ParseFromString(response);
148 if (!result)
149 return false; // Not formatted properly.
150
151 ClusterMap new_cluster_data;
152 for (int i = 0; i < response_proto.clusters_size(); ++i) {
153 const image_collections::ClusterResponse_Cluster cluster =
battre 2014/10/07 13:39:28 nit/opt: You could store the result as a const ref
noyau (Ping after 24h) 2014/10/07 15:19:31 Used auto&
154 response_proto.clusters(i);
155 const std::string& title = cluster.title();
156 if (title.empty())
157 continue;
158 std::vector<std::string> starids;
battre 2014/10/07 13:39:28 stars_ids? (plural and underscore)
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
159 for (int j = 0; j < cluster.docs_size(); ++j) {
160 const std::string& doc = cluster.docs(j);
161 if (!doc.empty())
162 starids.push_back(doc);
163 }
164 if (starids.size())
165 new_cluster_data[title] = starids;
166 }
167
168 if (new_cluster_data.size() == cluster_data_.size() &&
169 std::equal(new_cluster_data.begin(),
170 new_cluster_data.end(),
171 cluster_data_.begin())) {
172 *should_notify = false;
173 } else {
174 UpdateModel(&new_cluster_data);
battre 2014/10/07 13:39:29 Do you want to call this SwapModel?
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
175 }
176 return true;
177 }
178
179 void BookmarkServerClusterService::CleanAfterFailure() {
180 if (cluster_data_.empty())
181 return;
182
183 ClusterMap empty;
184 UpdateModel(&empty);
185 }
186
187 void BookmarkServerClusterService::EnhancedBookmarkModelLoaded() {
188 TriggerTokenRequest(false);
189 }
190
191 void BookmarkServerClusterService::EnhancedBookmarkAdded(
192 const BookmarkNode* node) {
193 // Nothing to do.
194 }
195
196 void BookmarkServerClusterService::EnhancedBookmarkRemoved(
197 const BookmarkNode* node) {
198 // It is possible to remove the entries from the map here, but as those are
199 // filtered in ClustersForBookmark() this is not strictly necessary.
200 }
201
202 void BookmarkServerClusterService::EnhancedBookmarkAllUserNodesRemoved() {
203 if (!cluster_data_.empty()) {
204 ClusterMap empty;
205 UpdateModel(&empty);
206 }
207 }
208
209 void BookmarkServerClusterService::EnhancedBookmarkRemoteIdChanged(
210 const BookmarkNode* node,
211 const std::string& old_remote_id,
212 const std::string& remote_id) {
213 std::vector<std::string> clusters;
214 for (ClusterMap::iterator it = cluster_data_.begin();
215 it != cluster_data_.end();
216 ++it) {
217 std::vector<std::string>& v = it->second;
218 std::replace(v.begin(), v.end(), old_remote_id, remote_id);
219 }
220 }
221
222 void BookmarkServerClusterService::GoogleSignedOut(
223 const std::string& account_id,
224 const std::string& username) {
225 if (!cluster_data_.empty()) {
226 ClusterMap empty;
227 UpdateModel(&empty);
battre 2014/10/07 13:39:29 You don't have unit tests. Did you check whether t
noyau (Ping after 24h) 2014/10/07 15:19:32 This returns the empty string when signed out. But
228 }
229 }
230
231 void BookmarkServerClusterService::UpdateModel(ClusterMap* cluster_map) {
232 cluster_data_.swap(*cluster_map);
233 const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
234 scoped_ptr<base::DictionaryValue> dictionary(
235 Serialize(cluster_data_, auth_id));
236 pref_service_->Set(prefs::kBookmarkClusters, *dictionary);
237 }
238
239 void BookmarkServerClusterService::LoadModel() {
240 const base::DictionaryValue* dictionary =
241 pref_service_->GetDictionary(prefs::kBookmarkClusters);
242 const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
243
244 ClusterMap loaded_data;
245 bool result = BookmarkServerClusterService::Deserialize(
246 *dictionary, auth_id, &loaded_data);
247 if (result)
248 cluster_data_.swap(loaded_data);
249 }
250
251 //
252 // Serialization.
253 //
254 scoped_ptr<base::DictionaryValue> BookmarkServerClusterService::Serialize(
255 const ClusterMap& cluster_map,
256
battre 2014/10/07 13:39:29 nit: remove empty line
noyau (Ping after 24h) 2014/10/07 15:19:31 Done.
257 const std::string& auth_id) {
258 // Create a list of all clusters. For each cluster, make another list. The
259 // first element in the list is the key (cluster name). All subsequent
260 // elements are stars ids.
261 scoped_ptr<base::ListValue> all_clusters(new base::ListValue);
262 for (auto it : cluster_map) {
battre 2014/10/07 13:39:29 auto&
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
263 scoped_ptr<base::ListValue> cluster(new base::ListValue);
264 cluster->AppendString(it.first);
265 cluster->AppendStrings(it.second);
266 all_clusters->Append(cluster.release());
267 }
268
269 // The dictionary that will be serialized has two fields: a version field and
270 // a data field.
271 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
battre 2014/10/07 13:39:28 I would be consistent with () in calls of the cons
noyau (Ping after 24h) 2014/10/07 15:19:31 Done.
272 data->SetInteger(kPrefServiceVersionKey, kPrefServiceVersion);
273 data->Set(kPrefServiceDataKey, all_clusters.release());
274 data->SetString(kAuthIdKey, auth_id);
275
276 return data.Pass();
277 }
278
279 bool BookmarkServerClusterService::Deserialize(
280 const base::DictionaryValue& value,
281
battre 2014/10/07 13:39:28 -newline
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
282 const std::string& auth_id,
283 ClusterMap* out_map) {
284 ClusterMap output;
285
286 // Check version.
287 int version;
288 if (!value.GetInteger(kPrefServiceVersionKey, &version))
289 return false;
290 if (version != kPrefServiceVersion)
291 return false;
292
293 // Check auth id.
294 std::string id;
295 if (!value.GetString(kAuthIdKey, &id))
296 return false;
297 if (id != auth_id)
298 return false;
299
300 base::ListValue const* all_clusters = NULL;
battre 2014/10/07 13:39:28 I think that the common syntax is "const base::Lis
noyau (Ping after 24h) 2014/10/07 15:19:32 Done.
301 if (!value.GetList(kPrefServiceDataKey, &all_clusters))
302 return false;
303
304 for (size_t index = 0; index < all_clusters->GetSize(); ++index) {
305 base::ListValue const* cluster = NULL;
306 if (!all_clusters->GetList(index, &cluster))
307 return false;
308 if (cluster->GetSize() < 1)
309 return false;
310 std::string key;
311 if (!cluster->GetString(0, &key))
312 return false;
313 std::vector<std::string> stars_ids;
314 for (size_t index = 1; index < cluster->GetSize(); ++index) {
315 std::string stars_id;
316 if (!cluster->GetString(index, &stars_id))
317 return false;
318 stars_ids.push_back(stars_id);
319 }
320 output.insert(std::make_pair(key, stars_ids));
321 }
322 out_map->swap(output);
323 return true;
324 }
325
326 } // namespace enhanced_bookmarks
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698