summaryrefslogtreecommitdiffstats
path: root/components/enhanced_bookmarks/bookmark_server_cluster_service.cc
diff options
context:
space:
mode:
authornoyau <noyau@chromium.org>2014-10-07 15:00:43 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-07 22:01:00 +0000
commit6bb374fc58bfeeb7966b6a548b1c7b41af9c8e47 (patch)
tree7b9d87b6c35ea4350be96c62016e5c2a77fd5d0b /components/enhanced_bookmarks/bookmark_server_cluster_service.cc
parentda97e832e41826d3ce0e6bd5c495feb636345ece (diff)
downloadchromium_src-6bb374fc58bfeeb7966b6a548b1c7b41af9c8e47.zip
chromium_src-6bb374fc58bfeeb7966b6a548b1c7b41af9c8e47.tar.gz
chromium_src-6bb374fc58bfeeb7966b6a548b1c7b41af9c8e47.tar.bz2
Bring up of the enhanced bookmarks cluster service.
This service retrieves the cluster of bookmarks from the bookmark server. BUG=None Review URL: https://codereview.chromium.org/539173004 Cr-Commit-Position: refs/heads/master@{#298582}
Diffstat (limited to 'components/enhanced_bookmarks/bookmark_server_cluster_service.cc')
-rw-r--r--components/enhanced_bookmarks/bookmark_server_cluster_service.cc315
1 files changed, 315 insertions, 0 deletions
diff --git a/components/enhanced_bookmarks/bookmark_server_cluster_service.cc b/components/enhanced_bookmarks/bookmark_server_cluster_service.cc
new file mode 100644
index 0000000..9cdd243
--- /dev/null
+++ b/components/enhanced_bookmarks/bookmark_server_cluster_service.cc
@@ -0,0 +1,315 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/enhanced_bookmarks/bookmark_server_cluster_service.h"
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/pref_service.h"
+#include "base/values.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
+#include "components/enhanced_bookmarks/enhanced_bookmark_utils.h"
+#include "components/enhanced_bookmarks/pref_names.h"
+#include "components/enhanced_bookmarks/proto/cluster.pb.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "net/base/url_util.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace {
+const std::string kClusterUrl("https://www.google.com/stars/cluster");
+const int kPrefServiceVersion = 1;
+const char* kPrefServiceVersionKey = "version";
+const char* kPrefServiceDataKey = "data";
+const char* kAuthIdKey = "auth_id";
+} // namespace
+
+namespace enhanced_bookmarks {
+
+BookmarkServerClusterService::BookmarkServerClusterService(
+ const std::string& application_language_code,
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ ProfileOAuth2TokenService* token_service,
+ SigninManagerBase* signin_manager,
+ enhanced_bookmarks::EnhancedBookmarkModel* enhanced_bookmark_model,
+ PrefService* pref_service)
+ : BookmarkServerService(request_context_getter,
+ token_service,
+ signin_manager,
+ enhanced_bookmark_model),
+ application_language_code_(application_language_code),
+ pref_service_(pref_service) {
+ LoadModel();
+
+ if (model_->loaded())
+ TriggerTokenRequest(false);
+
+ GetSigninManager()->AddObserver(this);
+}
+
+BookmarkServerClusterService::~BookmarkServerClusterService() {
+ GetSigninManager()->RemoveObserver(this);
+}
+
+const std::vector<const BookmarkNode*>
+BookmarkServerClusterService::BookmarksForClusterNamed(
+ const std::string& cluster_name) const {
+ std::vector<const BookmarkNode*> results;
+
+ ClusterMap::const_iterator cluster_it = cluster_data_.find(cluster_name);
+ if (cluster_it == cluster_data_.end())
+ return results;
+
+ for (auto& star_id : cluster_it->second) {
+ const BookmarkNode* bookmark = BookmarkForRemoteId(star_id);
+ if (bookmark)
+ results.push_back(bookmark);
+ }
+ return results;
+}
+
+const std::vector<std::string>
+BookmarkServerClusterService::ClustersForBookmark(
+ const BookmarkNode* bookmark) const {
+ const std::string& star_id = RemoteIDForBookmark(bookmark);
+
+ // TODO(noyau): if this turns out to be a perf bottleneck this may be improved
+ // by storing a reverse map from id to cluster.
+ std::vector<std::string> clusters;
+ for (auto& pair : cluster_data_) {
+ const std::vector<std::string>& stars_ids = pair.second;
+ if (std::find(stars_ids.begin(), stars_ids.end(), star_id) !=
+ stars_ids.end())
+ clusters.push_back(pair.first);
+ }
+ return clusters;
+}
+
+const std::vector<std::string> BookmarkServerClusterService::GetClusters()
+ const {
+ std::vector<std::string> cluster_names;
+
+ for (auto& pair : cluster_data_)
+ cluster_names.push_back(pair.first);
+
+ return cluster_names;
+}
+
+// static
+void BookmarkServerClusterService::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterDictionaryPref(
+ prefs::kBookmarkClusters,
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
+scoped_ptr<net::URLFetcher> BookmarkServerClusterService::CreateFetcher() {
+ // Add the necessary arguments to the URI.
+ GURL url(kClusterUrl);
+ url = net::AppendQueryParameter(url, "output", "proto");
+
+ // Append language.
+ if (!application_language_code_.empty())
+ url = net::AppendQueryParameter(url, "hl", application_language_code_);
+
+ url = net::AppendQueryParameter(url, "v", model_->GetVersionString());
+
+ // Build the URLFetcher to perform the request.
+ scoped_ptr<net::URLFetcher> url_fetcher(
+ net::URLFetcher::Create(url, net::URLFetcher::POST, this));
+
+ // Binary encode a basic request proto.
+ image_collections::ClusterRequest request_proto;
+ request_proto.set_cluster_all(true);
+
+ std::string proto_output;
+ bool result = request_proto.SerializePartialToString(&proto_output);
+ DCHECK(result);
+
+ url_fetcher->SetUploadData("application/octet-stream", proto_output);
+ return url_fetcher;
+}
+
+bool BookmarkServerClusterService::ProcessResponse(const std::string& response,
+ bool* should_notify) {
+ DCHECK(*should_notify);
+ image_collections::ClusterResponse response_proto;
+ bool result = response_proto.ParseFromString(response);
+ if (!result)
+ return false; // Not formatted properly.
+
+ ClusterMap new_cluster_data;
+ for (const auto& cluster : response_proto.clusters()) {
+ const std::string& title = cluster.title();
+ if (title.empty())
+ continue;
+ std::vector<std::string> stars_ids;
+ for (auto& doc : cluster.docs()) {
+ if (!doc.empty())
+ stars_ids.push_back(doc);
+ }
+ if (stars_ids.size())
+ new_cluster_data[title] = stars_ids;
+ }
+
+ if (new_cluster_data.size() == cluster_data_.size() &&
+ std::equal(new_cluster_data.begin(),
+ new_cluster_data.end(),
+ cluster_data_.begin())) {
+ *should_notify = false;
+ } else {
+ SwapModel(&new_cluster_data);
+ }
+ return true;
+}
+
+void BookmarkServerClusterService::CleanAfterFailure() {
+ if (cluster_data_.empty())
+ return;
+
+ ClusterMap empty;
+ SwapModel(&empty);
+}
+
+void BookmarkServerClusterService::EnhancedBookmarkModelLoaded() {
+ TriggerTokenRequest(false);
+}
+
+void BookmarkServerClusterService::EnhancedBookmarkAdded(
+ const BookmarkNode* node) {
+ // Nothing to do.
+}
+
+void BookmarkServerClusterService::EnhancedBookmarkRemoved(
+ const BookmarkNode* node) {
+ // It is possible to remove the entries from the map here, but as those are
+ // filtered in ClustersForBookmark() this is not strictly necessary.
+}
+
+void BookmarkServerClusterService::EnhancedBookmarkAllUserNodesRemoved() {
+ if (!cluster_data_.empty()) {
+ ClusterMap empty;
+ SwapModel(&empty);
+ }
+}
+
+void BookmarkServerClusterService::EnhancedBookmarkRemoteIdChanged(
+ const BookmarkNode* node,
+ const std::string& old_remote_id,
+ const std::string& remote_id) {
+ std::vector<std::string> clusters;
+ for (auto& pair : cluster_data_) {
+ std::vector<std::string>& stars_ids = pair.second;
+ std::replace(stars_ids.begin(), stars_ids.end(), old_remote_id, remote_id);
+ }
+}
+
+void BookmarkServerClusterService::GoogleSignedOut(
+ const std::string& account_id,
+ const std::string& username) {
+ if (!cluster_data_.empty()) {
+ ClusterMap empty;
+ SwapModel(&empty);
+ }
+}
+
+void BookmarkServerClusterService::SwapModel(ClusterMap* cluster_map) {
+ cluster_data_.swap(*cluster_map);
+ const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
+ scoped_ptr<base::DictionaryValue> dictionary(
+ Serialize(cluster_data_, auth_id));
+ pref_service_->Set(prefs::kBookmarkClusters, *dictionary);
+}
+
+void BookmarkServerClusterService::LoadModel() {
+ const base::DictionaryValue* dictionary =
+ pref_service_->GetDictionary(prefs::kBookmarkClusters);
+ const std::string& auth_id = GetSigninManager()->GetAuthenticatedAccountId();
+
+ ClusterMap loaded_data;
+ bool result = BookmarkServerClusterService::Deserialize(
+ *dictionary, auth_id, &loaded_data);
+ if (result)
+ cluster_data_.swap(loaded_data);
+}
+
+//
+// Serialization.
+//
+// static
+scoped_ptr<base::DictionaryValue> BookmarkServerClusterService::Serialize(
+ const ClusterMap& cluster_map,
+ const std::string& auth_id) {
+ // Create a list of all clusters. For each cluster, make another list. The
+ // first element in the list is the key (cluster name). All subsequent
+ // elements are stars ids.
+ scoped_ptr<base::ListValue> all_clusters(new base::ListValue);
+ for (auto& pair : cluster_map) {
+ scoped_ptr<base::ListValue> cluster(new base::ListValue);
+ cluster->AppendString(pair.first);
+ cluster->AppendStrings(pair.second);
+ all_clusters->Append(cluster.release());
+ }
+
+ // The dictionary that will be serialized has two fields: a version field and
+ // a data field.
+ scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue);
+ data->SetInteger(kPrefServiceVersionKey, kPrefServiceVersion);
+ data->Set(kPrefServiceDataKey, all_clusters.release());
+ data->SetString(kAuthIdKey, auth_id);
+
+ return data.Pass();
+}
+
+// static
+bool BookmarkServerClusterService::Deserialize(
+ const base::DictionaryValue& value,
+ const std::string& auth_id,
+ ClusterMap* out_map) {
+ ClusterMap output;
+
+ // Check version.
+ int version;
+ if (!value.GetInteger(kPrefServiceVersionKey, &version))
+ return false;
+ if (version != kPrefServiceVersion)
+ return false;
+
+ // Check auth id.
+ std::string id;
+ if (!value.GetString(kAuthIdKey, &id))
+ return false;
+ if (id != auth_id)
+ return false;
+
+ const base::ListValue* all_clusters = NULL;
+ if (!value.GetList(kPrefServiceDataKey, &all_clusters))
+ return false;
+
+ for (size_t index = 0; index < all_clusters->GetSize(); ++index) {
+ const base::ListValue* cluster = NULL;
+ if (!all_clusters->GetList(index, &cluster))
+ return false;
+ if (cluster->GetSize() < 1)
+ return false;
+ std::string key;
+ if (!cluster->GetString(0, &key))
+ return false;
+ std::vector<std::string> stars_ids;
+ for (size_t index = 1; index < cluster->GetSize(); ++index) {
+ std::string stars_id;
+ if (!cluster->GetString(index, &stars_id))
+ return false;
+ stars_ids.push_back(stars_id);
+ }
+ output.insert(std::make_pair(key, stars_ids));
+ }
+ out_map->swap(output);
+ return true;
+}
+
+} // namespace enhanced_bookmarks