Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / bookmarks / chrome_bookmark_client.cc
blob15d835dfab200beeea3eedbb97b5f15cb477295c
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.
5 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/values.h"
11 #include "chrome/browser/favicon/favicon_service.h"
12 #include "chrome/browser/favicon/favicon_service_factory.h"
13 #include "chrome/browser/history/history_service.h"
14 #include "chrome/browser/policy/profile_policy_connector.h"
15 #include "chrome/browser/policy/profile_policy_connector_factory.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "components/bookmarks/browser/bookmark_model.h"
18 #include "components/bookmarks/browser/bookmark_node.h"
19 #include "components/bookmarks/browser/bookmark_utils.h"
20 #include "components/history/core/browser/url_database.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_details.h"
23 #include "content/public/browser/notification_source.h"
24 #include "content/public/browser/user_metrics.h"
25 #include "grit/components_strings.h"
26 #include "policy/policy_constants.h"
27 #include "ui/base/l10n/l10n_util.h"
29 using bookmarks::BookmarkModel;
30 using bookmarks::BookmarkNode;
31 using bookmarks::BookmarkPermanentNode;
33 namespace {
35 void RunCallbackWithImage(
36 const favicon_base::FaviconImageCallback& callback,
37 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
38 favicon_base::FaviconImageResult result;
39 if (bitmap_result.is_valid()) {
40 result.image = gfx::Image::CreateFrom1xPNGBytes(
41 bitmap_result.bitmap_data->front(), bitmap_result.bitmap_data->size());
42 result.icon_url = bitmap_result.icon_url;
43 callback.Run(result);
44 return;
46 callback.Run(result);
49 void LoadInitialContents(BookmarkPermanentNode* node,
50 base::ListValue* initial_bookmarks,
51 int64* next_node_id) {
52 // Load the initial contents of the |node| now, and assign it an unused ID.
53 int64 id = *next_node_id;
54 node->set_id(id);
55 *next_node_id = policy::ManagedBookmarksTracker::LoadInitial(
56 node, initial_bookmarks, id + 1);
57 node->set_visible(!node->empty());
60 } // namespace
62 ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile)
63 : profile_(profile),
64 history_service_(NULL),
65 model_(NULL),
66 managed_node_(NULL),
67 supervised_node_(NULL) {
70 ChromeBookmarkClient::~ChromeBookmarkClient() {
73 void ChromeBookmarkClient::Init(BookmarkModel* model) {
74 DCHECK(model);
75 DCHECK(!model_);
76 model_ = model;
77 model_->AddObserver(this);
79 managed_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
80 model_,
81 profile_->GetPrefs(),
82 false,
83 base::Bind(&ChromeBookmarkClient::GetManagedBookmarksDomain,
84 base::Unretained(this))));
85 supervised_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
86 model_,
87 profile_->GetPrefs(),
88 true,
89 base::Callback<std::string()>()));
92 void ChromeBookmarkClient::Shutdown() {
93 favicon_changed_subscription_.reset();
94 if (model_) {
95 model_->RemoveObserver(this);
96 model_ = NULL;
98 BookmarkClient::Shutdown();
101 bool ChromeBookmarkClient::PreferTouchIcon() {
102 #if !defined(OS_IOS)
103 return false;
104 #else
105 return true;
106 #endif
109 base::CancelableTaskTracker::TaskId
110 ChromeBookmarkClient::GetFaviconImageForPageURL(
111 const GURL& page_url,
112 favicon_base::IconType type,
113 const favicon_base::FaviconImageCallback& callback,
114 base::CancelableTaskTracker* tracker) {
115 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
116 profile_, ServiceAccessType::EXPLICIT_ACCESS);
117 if (!favicon_service)
118 return base::CancelableTaskTracker::kBadTaskId;
119 if (type == favicon_base::FAVICON) {
120 return favicon_service->GetFaviconImageForPageURL(
121 page_url, callback, tracker);
122 } else {
123 return favicon_service->GetRawFaviconForPageURL(
124 page_url,
125 type,
127 base::Bind(&RunCallbackWithImage, callback),
128 tracker);
132 bool ChromeBookmarkClient::SupportsTypedCountForNodes() {
133 return true;
136 void ChromeBookmarkClient::GetTypedCountForNodes(
137 const NodeSet& nodes,
138 NodeTypedCountPairs* node_typed_count_pairs) {
139 history::URLDatabase* url_db =
140 history_service_ ? history_service_->InMemoryDatabase() : NULL;
141 for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
142 int typed_count = 0;
144 // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but
145 // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot
146 // fetch the URLRow, it is safe to assume that its |typed_count| is 0.
147 history::URLRow url;
148 if (url_db && url_db->GetRowForURL((*i)->url(), &url))
149 typed_count = url.typed_count();
151 NodeTypedCountPair pair(*i, typed_count);
152 node_typed_count_pairs->push_back(pair);
156 bool ChromeBookmarkClient::IsPermanentNodeVisible(
157 const BookmarkPermanentNode* node) {
158 DCHECK(node->type() == BookmarkNode::BOOKMARK_BAR ||
159 node->type() == BookmarkNode::OTHER_NODE ||
160 node->type() == BookmarkNode::MOBILE ||
161 node == managed_node_ ||
162 node == supervised_node_);
163 if (node == managed_node_ || node == supervised_node_)
164 return false;
165 #if !defined(OS_IOS)
166 return node->type() != BookmarkNode::MOBILE;
167 #else
168 return node->type() == BookmarkNode::MOBILE;
169 #endif
172 void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
173 content::RecordAction(action);
176 bookmarks::LoadExtraCallback ChromeBookmarkClient::GetLoadExtraNodesCallback() {
177 // Create the managed_node_ and supervised_node_ with a temporary ID of 0 now.
178 // They will be populated (and assigned proper IDs) in the LoadExtraNodes
179 // callback.
180 // The ownership of managed_node_ and supervised_node_ is in limbo until
181 // LoadExtraNodes runs, so we leave them in the care of the closure meanwhile.
182 scoped_ptr<BookmarkPermanentNode> managed(new BookmarkPermanentNode(0));
183 managed_node_ = managed.get();
184 scoped_ptr<BookmarkPermanentNode> supervised(new BookmarkPermanentNode(0));
185 supervised_node_ = supervised.get();
187 return base::Bind(
188 &ChromeBookmarkClient::LoadExtraNodes,
189 base::Passed(&managed),
190 base::Passed(managed_bookmarks_tracker_->GetInitialManagedBookmarks()),
191 base::Passed(&supervised),
192 base::Passed(
193 supervised_bookmarks_tracker_->GetInitialManagedBookmarks()));
196 bool ChromeBookmarkClient::CanSetPermanentNodeTitle(
197 const BookmarkNode* permanent_node) {
198 // The |managed_node_| can have its title updated if the user signs in or
199 // out, since the name of the managed domain can appear in it. The
200 // |supervised_node_| has a fixed title which can never be updated.
201 return (!bookmarks::IsDescendantOf(permanent_node, managed_node_) &&
202 !bookmarks::IsDescendantOf(permanent_node, supervised_node_)) ||
203 permanent_node == managed_node_;
206 bool ChromeBookmarkClient::CanSyncNode(const BookmarkNode* node) {
207 return !bookmarks::IsDescendantOf(node, managed_node_) &&
208 !bookmarks::IsDescendantOf(node, supervised_node_);
211 bool ChromeBookmarkClient::CanBeEditedByUser(const BookmarkNode* node) {
212 return !bookmarks::IsDescendantOf(node, managed_node_) &&
213 !bookmarks::IsDescendantOf(node, supervised_node_);
216 void ChromeBookmarkClient::SetHistoryService(HistoryService* history_service) {
217 DCHECK(history_service);
218 history_service_ = history_service;
219 favicon_changed_subscription_ = history_service_->AddFaviconChangedCallback(
220 base::Bind(&BookmarkModel::OnFaviconChanged, base::Unretained(model_)));
223 void ChromeBookmarkClient::BookmarkModelChanged() {
226 void ChromeBookmarkClient::BookmarkNodeRemoved(
227 BookmarkModel* model,
228 const BookmarkNode* parent,
229 int old_index,
230 const BookmarkNode* node,
231 const std::set<GURL>& removed_urls) {
232 if (history_service_)
233 history_service_->URLsNoLongerBookmarked(removed_urls);
236 void ChromeBookmarkClient::BookmarkAllUserNodesRemoved(
237 BookmarkModel* model,
238 const std::set<GURL>& removed_urls) {
239 if (history_service_)
240 history_service_->URLsNoLongerBookmarked(removed_urls);
243 void ChromeBookmarkClient::BookmarkModelLoaded(BookmarkModel* model,
244 bool ids_reassigned) {
245 // Start tracking the managed and supervised bookmarks. This will detect any
246 // changes that may have occurred while the initial managed and supervised
247 // bookmarks were being loaded on the background.
248 managed_bookmarks_tracker_->Init(managed_node_);
249 supervised_bookmarks_tracker_->Init(supervised_node_);
252 // static
253 bookmarks::BookmarkPermanentNodeList ChromeBookmarkClient::LoadExtraNodes(
254 scoped_ptr<BookmarkPermanentNode> managed_node,
255 scoped_ptr<base::ListValue> initial_managed_bookmarks,
256 scoped_ptr<BookmarkPermanentNode> supervised_node,
257 scoped_ptr<base::ListValue> initial_supervised_bookmarks,
258 int64* next_node_id) {
259 LoadInitialContents(
260 managed_node.get(), initial_managed_bookmarks.get(), next_node_id);
261 managed_node->SetTitle(l10n_util::GetStringUTF16(
262 IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));
264 LoadInitialContents(
265 supervised_node.get(), initial_supervised_bookmarks.get(), next_node_id);
266 supervised_node->SetTitle(l10n_util::GetStringUTF16(
267 IDS_BOOKMARK_BAR_SUPERVISED_FOLDER_DEFAULT_NAME));
269 bookmarks::BookmarkPermanentNodeList extra_nodes;
270 // Ownership of the managed and supervised nodes passed to the caller.
271 extra_nodes.push_back(managed_node.release());
272 extra_nodes.push_back(supervised_node.release());
274 return extra_nodes.Pass();
277 std::string ChromeBookmarkClient::GetManagedBookmarksDomain() {
278 policy::ProfilePolicyConnector* connector =
279 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_);
280 if (connector->IsPolicyFromCloudPolicy(policy::key::kManagedBookmarks))
281 return connector->GetManagementDomain();
282 return std::string();