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

Unified Diff: chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc

Issue 769153007: Managed bookmarks for supervised users (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc
diff --git a/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc b/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2b12354365b12f4b96aabe7cfa5a986dd4ac95ba
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc
@@ -0,0 +1,190 @@
+// 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 "chrome/browser/supervised_user/supervised_user_bookmarks_handler.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/values.h"
+#include "components/url_fixer/url_fixer.h"
+
+namespace {
+
+const char kKeyLink[] = "SupervisedBookmarkLink";
Pam (message me for reviews) 2015/01/14 14:03:37 A little more description of where these keys appl
Marc Treib 2015/01/14 16:40:50 Done.
+const char kKeyFolder[] = "SupervisedBookmarkFolder";
+
+const char kId[] = "id";
+const char kName[] = "name";
+const char kUrl[] = "url";
+const char kChildren[] = "children";
+
+bool ExtractId(const std::string& key, int* id) {
+ // |key| can be either "<ID>-<Value>" or just "<ID>".
Pam (message me for reviews) 2015/01/14 14:03:37 Under what circumstances does each of these |key|
Marc Treib 2015/01/14 16:40:50 Updated the comment. And yes, that should be ":",
+ std::string id_str = key.substr(0, key.find_first_of(':'));
+ if (!base::StringToInt(id_str, id)) {
+ LOG(WARNING) << "Failed to parse id from " << key;
+ return false;
+ }
+ LOG_IF(WARNING, *id < 0) << "IDs should be >= 0, but got "
+ << *id << " from " << key;
+ return true;
+}
+
+bool ExtractValue(const std::string& key, std::string* value) {
+ // |key| must be "<ID>-<Value>".
Pam (message me for reviews) 2015/01/14 14:03:37 - --> :
Marc Treib 2015/01/14 16:40:50 Done.
+ size_t pos = key.find_first_of(':');
+ if (pos == std::string::npos) {
+ LOG(WARNING) << "Failed to parse value from " << key;
+ return false;
+ }
+ *value = key.substr(pos + 1);
+ return true;
+}
+
+bool ExtractIdAndValue(const std::string& key, int* id, std::string* value) {
+ return ExtractId(key, id) && ExtractValue(key, value);
+}
+
+base::ListValue* FindNode(base::ListValue* root, int id) {
Pam (message me for reviews) 2015/01/14 14:03:37 FindFolder would be a clearer function name. Also,
Marc Treib 2015/01/14 16:40:50 Done.
+ if (id == 0) // We're looking for the root folder. Assume this is it.
+ return root;
+
+ for (size_t i = 0; i < root->GetSize(); ++i) {
+ base::DictionaryValue* item = nullptr;
+ root->GetDictionary(i, &item);
+ DCHECK_NE(item, (base::DictionaryValue*)nullptr);
+
+ base::ListValue* children;
+ if (!item->GetList(kChildren, &children))
+ continue; // Skip bookmarks. Only interested in folders.
+
+ // Is this it?
+ int node_id;
+ if (item->GetInteger(kId, &node_id) && node_id == id)
+ return children;
+
+ // Recurse.
+ base::ListValue* result = FindNode(children, id);
+ if (result)
+ return result;
+ }
+ return nullptr;
+}
+
+} // namespace
+
+SupervisedUserBookmarksHandler::Folder::Folder(
+ int id, const std::string& name, int parent_id)
+ : id(id), name(name), parent_id(parent_id) {
+}
+
+SupervisedUserBookmarksHandler::Link::Link(
+ const std::string& url, const std::string& name, int parent_id)
+ : url(url), name(name), parent_id(parent_id) {
+}
+
+SupervisedUserBookmarksHandler::SupervisedUserBookmarksHandler() {
+}
+
+SupervisedUserBookmarksHandler::~SupervisedUserBookmarksHandler() {
+}
+
+scoped_ptr<base::ListValue> SupervisedUserBookmarksHandler::BuildBookmarksTree(
+ const base::DictionaryValue& settings) {
+ SupervisedUserBookmarksHandler handler;
+ handler.ParseSettings(settings);
+ return handler.BuildTree();
+}
+
+void SupervisedUserBookmarksHandler::ParseSettings(
+ const base::DictionaryValue& settings) {
+ const base::DictionaryValue* folders;
+ if (settings.GetDictionary(kKeyFolder, &folders))
+ ParseFolders(*folders);
+
+ const base::DictionaryValue* links;
+ if (settings.GetDictionary(kKeyLink, &links))
+ ParseLinks(*links);
+}
+
+void SupervisedUserBookmarksHandler::ParseFolders(
+ const base::DictionaryValue& folders) {
+ for (base::DictionaryValue::Iterator it(folders); !it.IsAtEnd();
+ it.Advance()) {
+ int id;
+ if (!ExtractId(it.key(), &id))
+ continue;
+ std::string value;
+ it.value().GetAsString(&value);
+ std::string name;
+ int parent_id;
+ if (!ExtractIdAndValue(value, &parent_id, &name))
+ continue;
+ folders_.push_back(Folder(id, name, parent_id));
+ }
+}
+
+void SupervisedUserBookmarksHandler::ParseLinks(
+ const base::DictionaryValue& links) {
+ for (base::DictionaryValue::Iterator it(links); !it.IsAtEnd(); it.Advance()) {
+ std::string url;
+ if (!ExtractValue(it.key(), &url))
+ continue;
+ std::string value;
+ it.value().GetAsString(&value);
+ std::string name;
+ int parent_id;
+ if (!ExtractIdAndValue(value, &parent_id, &name))
+ continue;
+ links_.push_back(Link(url, name, parent_id));
Pam (message me for reviews) 2015/01/14 14:03:37 I'm almost tempted to make a union for id|url, and
Marc Treib 2015/01/14 16:40:50 Hrm. I agree that the mostly-duplicated code isn't
Pam (message me for reviews) 2015/01/15 11:37:04 Could also be a struct or class with separate url
+ }
+}
+
+scoped_ptr<base::ListValue> SupervisedUserBookmarksHandler::BuildTree() {
+ root_.reset(new base::ListValue);
+ AddFoldersToTree();
+ AddLinksToTree();
+ return root_.Pass();
+}
+
+void SupervisedUserBookmarksHandler::AddFoldersToTree() {
+ std::vector<Folder> folders = folders_;
+ std::vector<Folder> folders_failed;
+ while (!folders.empty() && folders.size() != folders_failed.size()) {
Pam (message me for reviews) 2015/01/14 14:03:37 This snippet is a bit hard to understand. A commen
Marc Treib 2015/01/14 16:40:50 Done.
+ folders_failed.clear();
+ for (const auto& folder : folders) {
+ scoped_ptr<base::DictionaryValue> node(new base::DictionaryValue);
+ node->SetIntegerWithoutPathExpansion(kId, folder.id);
+ node->SetStringWithoutPathExpansion(kName, folder.name);
+ node->SetWithoutPathExpansion(kChildren, new base::ListValue);
+ if (!AddNodeToTree(folder.parent_id, node.Pass()))
+ folders_failed.push_back(folder);
+ }
+ folders.swap(folders_failed);
+ }
+}
+
+void SupervisedUserBookmarksHandler::AddLinksToTree() {
+ for (const auto& link : links_) {
+ scoped_ptr<base::DictionaryValue> node(new base::DictionaryValue);
+ GURL url = url_fixer::FixupURL(link.url, std::string());
+ if (!url.is_valid()) {
+ DLOG(WARNING) << "Got invalid URL: " << link.url;
+ continue;
+ }
+ node->SetStringWithoutPathExpansion(kUrl, url.spec());
+ node->SetStringWithoutPathExpansion(kName, link.name);
+ AddNodeToTree(link.parent_id, node.Pass());
Pam (message me for reviews) 2015/01/14 14:03:37 Also consider logging a warning if the bookmark ca
Marc Treib 2015/01/14 16:40:50 Done.
+ }
+}
+
+bool SupervisedUserBookmarksHandler::AddNodeToTree(
+ int parent_id,
+ scoped_ptr<base::DictionaryValue> node) {
+ base::ListValue* parent = FindNode(root_.get(), parent_id);
+ if (!parent)
+ return false;
+ parent->Append(node.release());
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698