ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / android / bookmarks / partner_bookmarks_shim.cc
blob565e723e5e1bef94301077a682ea2754457fa6ad
1 // Copyright 2013 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.
5 #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h"
7 #include "base/lazy_instance.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/values.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/pref_names.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "components/pref_registry/pref_registry_syncable.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
17 using bookmarks::BookmarkNode;
18 using content::BrowserThread;
20 namespace {
22 // PartnerModelKeeper is used as a singleton to store an immutable hierarchy
23 // of partner bookmarks. The hierarchy is retrieved from the partner bookmarks
24 // provider and doesn't depend on the user profile.
25 // The retrieved hierarchy persists
26 // PartnerBookmarksShim is responsible to applying and storing the user changes
27 // (deletions/renames) in the user profile, thus keeping the hierarchy intact.
28 struct PartnerModelKeeper {
29 scoped_ptr<BookmarkNode> partner_bookmarks_root;
30 bool loaded;
32 PartnerModelKeeper()
33 : loaded(false) {}
36 base::LazyInstance<PartnerModelKeeper> g_partner_model_keeper =
37 LAZY_INSTANCE_INITIALIZER;
39 const void* kPartnerBookmarksShimUserDataKey =
40 &kPartnerBookmarksShimUserDataKey;
42 // Dictionary keys for entries in the kPartnerBookmarksMapping pref.
43 static const char kMappingUrl[] = "url";
44 static const char kMappingProviderTitle[] = "provider_title";
45 static const char kMappingTitle[] = "mapped_title";
47 static bool g_disable_partner_bookmarks_editing = false;
49 } // namespace
51 // static
52 PartnerBookmarksShim* PartnerBookmarksShim::BuildForBrowserContext(
53 content::BrowserContext* browser_context) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56 PartnerBookmarksShim* data =
57 static_cast<PartnerBookmarksShim*>(
58 browser_context->GetUserData(kPartnerBookmarksShimUserDataKey));
59 if (data)
60 return data;
62 data = new PartnerBookmarksShim(
63 Profile::FromBrowserContext(browser_context)->GetPrefs());
64 browser_context->SetUserData(kPartnerBookmarksShimUserDataKey, data);
65 data->ReloadNodeMapping();
66 return data;
69 // static
70 void PartnerBookmarksShim::RegisterProfilePrefs(
71 user_prefs::PrefRegistrySyncable* registry) {
72 registry->RegisterListPref(
73 prefs::kPartnerBookmarkMappings,
74 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
77 // static
78 void PartnerBookmarksShim::DisablePartnerBookmarksEditing() {
79 g_disable_partner_bookmarks_editing = true;
82 bool PartnerBookmarksShim::IsLoaded() const {
83 return g_partner_model_keeper.Get().loaded;
86 bool PartnerBookmarksShim::HasPartnerBookmarks() const {
87 DCHECK(IsLoaded());
88 return g_partner_model_keeper.Get().partner_bookmarks_root.get() != NULL;
91 bool PartnerBookmarksShim::IsReachable(const BookmarkNode* node) const {
92 DCHECK(IsPartnerBookmark(node));
93 if (!HasPartnerBookmarks())
94 return false;
95 if (!g_disable_partner_bookmarks_editing) {
96 for (const BookmarkNode* i = node; i != NULL; i = i->parent()) {
97 const NodeRenamingMapKey key(i->url(), i->GetTitle());
98 NodeRenamingMap::const_iterator remap = node_rename_remove_map_.find(key);
99 if (remap != node_rename_remove_map_.end() && remap->second.empty())
100 return false;
103 return true;
106 bool PartnerBookmarksShim::IsEditable(const BookmarkNode* node) const {
107 DCHECK(IsPartnerBookmark(node));
108 if (!HasPartnerBookmarks())
109 return false;
110 if (g_disable_partner_bookmarks_editing)
111 return false;
112 return true;
115 void PartnerBookmarksShim::RemoveBookmark(const BookmarkNode* node) {
116 DCHECK(IsEditable(node));
117 RenameBookmark(node, base::string16());
120 void PartnerBookmarksShim::RenameBookmark(const BookmarkNode* node,
121 const base::string16& title) {
122 DCHECK(IsEditable(node));
123 const NodeRenamingMapKey key(node->url(), node->GetTitle());
124 node_rename_remove_map_[key] = title;
125 SaveNodeMapping();
126 FOR_EACH_OBSERVER(PartnerBookmarksShim::Observer, observers_,
127 PartnerShimChanged(this));
130 void PartnerBookmarksShim::AddObserver(
131 PartnerBookmarksShim::Observer* observer) {
132 observers_.AddObserver(observer);
135 void PartnerBookmarksShim::RemoveObserver(
136 PartnerBookmarksShim::Observer* observer) {
137 observers_.RemoveObserver(observer);
140 const BookmarkNode* PartnerBookmarksShim::GetNodeByID(int64 id) const {
141 DCHECK(IsLoaded());
142 if (!HasPartnerBookmarks())
143 return NULL;
144 return GetNodeByID(GetPartnerBookmarksRoot(), id);
147 base::string16 PartnerBookmarksShim::GetTitle(const BookmarkNode* node) const {
148 DCHECK(node);
149 DCHECK(IsPartnerBookmark(node));
151 if (!g_disable_partner_bookmarks_editing) {
152 const NodeRenamingMapKey key(node->url(), node->GetTitle());
153 NodeRenamingMap::const_iterator i = node_rename_remove_map_.find(key);
154 if (i != node_rename_remove_map_.end())
155 return i->second;
158 return node->GetTitle();
161 bool PartnerBookmarksShim::IsPartnerBookmark(const BookmarkNode* node) const {
162 DCHECK(IsLoaded());
163 if (!HasPartnerBookmarks())
164 return false;
165 const BookmarkNode* parent = node;
166 while (parent) {
167 if (parent == GetPartnerBookmarksRoot())
168 return true;
169 parent = parent->parent();
171 return false;
174 const BookmarkNode* PartnerBookmarksShim::GetPartnerBookmarksRoot() const {
175 return g_partner_model_keeper.Get().partner_bookmarks_root.get();
178 void PartnerBookmarksShim::SetPartnerBookmarksRoot(BookmarkNode* root_node) {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180 g_partner_model_keeper.Get().partner_bookmarks_root.reset(root_node);
181 g_partner_model_keeper.Get().loaded = true;
182 FOR_EACH_OBSERVER(PartnerBookmarksShim::Observer, observers_,
183 PartnerShimLoaded(this));
186 PartnerBookmarksShim::NodeRenamingMapKey::NodeRenamingMapKey(
187 const GURL& url, const base::string16& provider_title)
188 : url_(url), provider_title_(provider_title) {}
190 PartnerBookmarksShim::NodeRenamingMapKey::~NodeRenamingMapKey() {}
192 bool operator<(const PartnerBookmarksShim::NodeRenamingMapKey& a,
193 const PartnerBookmarksShim::NodeRenamingMapKey& b) {
194 return (a.url_ < b.url_) ||
195 (a.url_ == b.url_ && a.provider_title_ < b.provider_title_);
198 // static
199 void PartnerBookmarksShim::ClearInBrowserContextForTesting(
200 content::BrowserContext* browser_context) {
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202 browser_context->SetUserData(kPartnerBookmarksShimUserDataKey, 0);
205 // static
206 void PartnerBookmarksShim::ClearPartnerModelForTesting() {
207 g_partner_model_keeper.Get().loaded = false;
208 g_partner_model_keeper.Get().partner_bookmarks_root.reset(0);
211 // static
212 void PartnerBookmarksShim::EnablePartnerBookmarksEditing() {
213 g_disable_partner_bookmarks_editing = false;
216 PartnerBookmarksShim::PartnerBookmarksShim(PrefService* prefs)
217 : prefs_(prefs),
218 observers_(
219 ObserverList<PartnerBookmarksShim::Observer>::NOTIFY_EXISTING_ONLY) {
222 PartnerBookmarksShim::~PartnerBookmarksShim() {
223 FOR_EACH_OBSERVER(PartnerBookmarksShim::Observer, observers_,
224 ShimBeingDeleted(this));
227 const BookmarkNode* PartnerBookmarksShim::GetNodeByID(
228 const BookmarkNode* parent, int64 id) const {
229 if (parent->id() == id)
230 return parent;
231 for (int i = 0, child_count = parent->child_count(); i < child_count; ++i) {
232 const BookmarkNode* result = GetNodeByID(parent->GetChild(i), id);
233 if (result)
234 return result;
236 return NULL;
239 void PartnerBookmarksShim::ReloadNodeMapping() {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
242 node_rename_remove_map_.clear();
243 if (!prefs_)
244 return;
246 const base::ListValue* list =
247 prefs_->GetList(prefs::kPartnerBookmarkMappings);
248 if (!list)
249 return;
251 for (base::ListValue::const_iterator it = list->begin();
252 it != list->end(); ++it) {
253 const base::DictionaryValue* dict = NULL;
254 if (!*it || !(*it)->GetAsDictionary(&dict)) {
255 NOTREACHED();
256 continue;
259 std::string url;
260 base::string16 provider_title;
261 base::string16 mapped_title;
262 if (!dict->GetString(kMappingUrl, &url) ||
263 !dict->GetString(kMappingProviderTitle, &provider_title) ||
264 !dict->GetString(kMappingTitle, &mapped_title)) {
265 NOTREACHED();
266 continue;
269 const NodeRenamingMapKey key(GURL(url), provider_title);
270 node_rename_remove_map_[key] = mapped_title;
274 void PartnerBookmarksShim::SaveNodeMapping() {
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
276 if (!prefs_)
277 return;
279 base::ListValue list;
280 for (NodeRenamingMap::const_iterator i = node_rename_remove_map_.begin();
281 i != node_rename_remove_map_.end();
282 ++i) {
283 base::DictionaryValue* dict = new base::DictionaryValue();
284 dict->SetString(kMappingUrl, i->first.url().spec());
285 dict->SetString(kMappingProviderTitle, i->first.provider_title());
286 dict->SetString(kMappingTitle, i->second);
287 list.Append(dict);
289 prefs_->Set(prefs::kPartnerBookmarkMappings, list);