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

Side by Side Diff: chrome/browser/profiles/profile_statistics.cc

Issue 1248613003: Issue 501916 : Add data type counts to profile deletion flow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased and modified GetHistoryCount call with reference to https://codereview.chromium.org/1370493002 Created 5 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 2015 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 "chrome/browser/profiles/profile_statistics.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/task_runner.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
13 #include "chrome/browser/history/history_service_factory.h"
14 #include "chrome/browser/password_manager/password_store_factory.h"
15 #include "components/bookmarks/browser/bookmark_model.h"
16 #include "components/history/core/browser/history_service.h"
17 #include "components/password_manager/core/browser/password_store.h"
18 #include "components/password_manager/core/browser/password_store_consumer.h"
19 #include "content/public/browser/browser_thread.h"
20
21 using content::BrowserThread;
22
23 namespace {
24
25 struct ProfileStatValue {
26 int count;
achuithb 2015/10/02 23:48:36 Add a ctor like ProfileStatValue(int count, bool s
lwchkg 2015/10/09 19:36:25 Mike and I agreed to use ProfileStatValue in the f
27 bool success; // false means the statistics failed to load
28 };
29
30 class ProfileStatisticsAggregator
31 : public base::RefCountedThreadSafe<ProfileStatisticsAggregator> {
32 // This class collects statistical information about the profile and returns
33 // the information via a callback function. Currently bookmarks, history,
34 // logins and preferences are counted.
35 //
36 // The class is RefCounted because this is needed for CancelableTaskTracker
37 // to function properly. Once all tasks are run (or cancelled) the instance is
38 // automatically destructed.
39 //
40 // The class is used internally by GetProfileStatistics function.
Roger Tawa OOO till Jul 10th 2015/10/16 12:22:35 Put this comment above class declaration at line 3
lwchkg 2015/10/17 14:06:45 Acknowledged.
41
42 public:
43 // Constructor
achuithb 2015/10/02 23:48:36 drop this comment
lwchkg 2015/10/09 19:36:25 Acknowledged.
44 explicit ProfileStatisticsAggregator(Profile* profile,
45 const profiles::ProfileStatisticsCallback& callback,
46 base::CancelableTaskTracker* tracker);
Roger Tawa OOO till Jul 10th 2015/10/16 12:22:35 Don't need explicit for ctor wirh more than one ar
lwchkg 2015/10/17 14:06:45 Acknowledged.
47
48 private:
49 // Destructor
50 friend class base::RefCountedThreadSafe<ProfileStatisticsAggregator>;
51 ~ProfileStatisticsAggregator() {}
52
53 Profile* profile_;
achuithb 2015/10/02 23:48:36 I think it's more common to have data members foll
lwchkg 2015/10/09 19:36:25 Acknowledged.
54 profiles::ProfileCategoryStats profile_category_stats_;
55
56 // Callback function to be called when results arrive. Will be called
57 // multiple times (once for each statistics).
58 const profiles::ProfileStatisticsCallback callback_;
achuithb 2015/10/02 23:48:36 It's a bit strange to have a const data member. We
lwchkg 2015/10/09 19:36:25 Agree. mlerman@: how do you think about this? ("co
59
60 base::CancelableTaskTracker* tracker_;
61
62 // Initialization. Called by constructors.
achuithb 2015/10/02 23:48:36 Drop this comment
lwchkg 2015/10/09 19:36:25 Acknowledged.
63 void Init();
achuithb 2015/10/02 23:48:36 What's the point of this method?
lwchkg 2015/10/09 19:36:25 So far we have only one constructor, so this metho
64
65 // Callback functions
66 // Normal callback. Appends result to |profile_category_stats_|, and then call
67 // the external callback. All other callbacks call this function.
68 void StatisticsCallback(const char* category, ProfileStatValue result);
69 // Callback for reporting success.
70 void StatisticsCallbackSuccess(const char* category, int count);
71 // Callback for reporting failure.
72 void StatisticsCallbackFailure(const char* category);
73 // Callback for history.
74 void StatisticsCallbackHistory(history::HistoryCountResult result);
75
76 // Bookmark counting.
77 static int CountBookmarksFromNode(const bookmarks::BookmarkNode* node);
achuithb 2015/10/02 23:48:36 Could you move this out of this class into the top
lwchkg 2015/10/09 19:36:25 Sounds good.
78 ProfileStatValue CountBookmarks() const;
79
80 // Preference counting.
81 ProfileStatValue CountPrefs() const;
82
83 // Password counting.
84 class PasswordStoreConsumerHelper
achuithb 2015/10/02 23:48:36 What's the point of this class? Why not have Profi
lwchkg 2015/10/09 19:36:25 I don't want PasswordStoreConsumer.* to pollute Pr
85 : public password_manager::PasswordStoreConsumer {
86 public:
87 explicit PasswordStoreConsumerHelper(ProfileStatisticsAggregator* parent)
88 : parent_(parent) {}
89
90 void OnGetPasswordStoreResults(
91 ScopedVector<autofill::PasswordForm> results) override {
92 parent_->StatisticsCallbackSuccess(profiles::kProfileStatisticsPasswords,
93 results.size());
94 }
95
96 private:
97 ProfileStatisticsAggregator* parent_;
achuithb 2015/10/02 23:48:36 parent_ = nullptr;
lwchkg 2015/10/09 19:36:25 Acknowledged.
98
99 DISALLOW_COPY_AND_ASSIGN(PasswordStoreConsumerHelper);
100 };
101 PasswordStoreConsumerHelper password_store_consumer_helper_;
102
103 DISALLOW_COPY_AND_ASSIGN(ProfileStatisticsAggregator);
104 };
105
106 ProfileStatisticsAggregator::ProfileStatisticsAggregator(
107 Profile* profile,
108 const profiles::ProfileStatisticsCallback& callback,
109 base::CancelableTaskTracker* tracker)
110 : profile_(profile),
111 callback_(callback),
112 tracker_(tracker),
113 password_store_consumer_helper_(this) {
114 Init();
115 }
116
117 void ProfileStatisticsAggregator::Init() {
118 // Initiate bookmark counting (async). Post to UI thread.
119 tracker_->PostTaskAndReplyWithResult(
120 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(),
121 FROM_HERE,
122 base::Bind(&ProfileStatisticsAggregator::CountBookmarks, this),
123 base::Bind(&ProfileStatisticsAggregator::StatisticsCallback,
124 this, profiles::kProfileStatisticsBookmarks));
125
126 // Initiate history counting (async).
127 history::HistoryService* history_service =
128 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
129
130 if (history_service) {
achuithb 2015/10/02 23:48:36 When can this be null?
lwchkg 2015/10/09 19:36:25 If GetForProfileWithoutCreating fails this is null
131 history_service->GetHistoryCount(
132 base::Time(),
133 base::Time::Max(),
134 base::Bind(&ProfileStatisticsAggregator::StatisticsCallbackHistory,
135 this),
136 tracker_);
137 } else {
138 StatisticsCallbackFailure(profiles::kProfileStatisticsBrowsingHistory);
139 }
140
141 // Initiate stored password counting (async).
142 // TODO(anthonyvd): make password task cancellable.
143 scoped_refptr<password_manager::PasswordStore> password_store =
144 PasswordStoreFactory::GetForProfile(
145 profile_, ServiceAccessType::EXPLICIT_ACCESS);
146 if (password_store) {
147 password_store->GetAutofillableLogins(&password_store_consumer_helper_);
148 } else {
149 StatisticsCallbackFailure(profiles::kProfileStatisticsPasswords);
150 }
151
152 // Initiate preference counting (async). Post to UI thread.
153 tracker_->PostTaskAndReplyWithResult(
154 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(),
155 FROM_HERE,
156 base::Bind(&ProfileStatisticsAggregator::CountPrefs, this),
157 base::Bind(&ProfileStatisticsAggregator::StatisticsCallback,
158 this, profiles::kProfileStatisticsSettings));
159 }
160
161 void ProfileStatisticsAggregator::StatisticsCallback(
162 const char* category, ProfileStatValue result) {
163 profiles::ProfileCategoryStat datum;
164 datum.category = category;
165 datum.count = result.count;
166 datum.success = result.success;
167 profile_category_stats_.push_back(datum);
168 callback_.Run(profile_category_stats_);
169 }
170
171 void ProfileStatisticsAggregator::StatisticsCallbackSuccess(
172 const char* category, int count) {
173 ProfileStatValue result;
174 result.count = count;
175 result.success = true;
176 StatisticsCallback(category, result);
177 }
178
179 void ProfileStatisticsAggregator::StatisticsCallbackFailure(
180 const char* category) {
181 ProfileStatValue result;
182 result.count = 0;
183 result.success = false;
184 StatisticsCallback(category, result);
185 }
186
187 void ProfileStatisticsAggregator::StatisticsCallbackHistory(
188 history::HistoryCountResult result) {
189 ProfileStatValue result_converted;
190 result_converted.count = result.count;
191 result_converted.success = result.success;
192 StatisticsCallback(profiles::kProfileStatisticsBrowsingHistory,
193 result_converted);
194 }
195
196 int ProfileStatisticsAggregator::CountBookmarksFromNode(
197 const bookmarks::BookmarkNode* node) {
198 int count = 0;
199 if (node->is_url()) {
200 ++count;
201 } else {
202 for (int i = 0; i < node->child_count(); ++i)
203 count += CountBookmarksFromNode(node->GetChild(i));
204 }
205 return count;
206 }
207
208 ProfileStatValue ProfileStatisticsAggregator::CountBookmarks() const {
209 bookmarks::BookmarkModel* bookmark_model =
210 BookmarkModelFactory::GetForProfileIfExists(profile_);
211
212 ProfileStatValue result;
213 if (bookmark_model) {
214 result.count = CountBookmarksFromNode(bookmark_model->bookmark_bar_node()) +
215 CountBookmarksFromNode(bookmark_model->other_node()) +
216 CountBookmarksFromNode(bookmark_model->mobile_node());
217 result.success = true;
218 } else {
219 result.count = 0;
220 result.success = false;
221 }
222 return result;
223 }
224
225 ProfileStatValue ProfileStatisticsAggregator::CountPrefs() const {
226 const PrefService* pref_service = profile_->GetPrefs();
227
228 ProfileStatValue result;
229 if (pref_service) {
230 scoped_ptr<base::DictionaryValue> prefs =
231 pref_service->GetPreferenceValuesWithoutPathExpansion();
232
233 int count = 0;
234 for (base::DictionaryValue::Iterator it(*(prefs.get()));
235 !it.IsAtEnd(); it.Advance()) {
236 const PrefService::Preference* pref = pref_service->
237 FindPreference(it.key());
238 // Skip all dictionaries (which must be empty by the function call above).
239 if (it.value().GetType() != base::Value::TYPE_DICTIONARY &&
240 pref && pref->IsUserControlled() && !pref->IsDefaultValue()) {
241 ++count;
242 }
243 }
244
245 result.count = count;
246 result.success = true;
247 } else {
248 result.count = 0;
249 result.success = false;
250 }
251 return result;
252 }
253
254 } // namespace
255
256 namespace profiles {
257
258 // Constants for the categories in ProfileCategoryStats
259 const char kProfileStatisticsBrowsingHistory[] = "BrowsingHistory";
260 const char kProfileStatisticsPasswords[] = "Passwords";
261 const char kProfileStatisticsBookmarks[] = "Bookmarks";
262 const char kProfileStatisticsSettings[] = "Settings";
263
264 void GetProfileStatistics(Profile* profile,
265 const ProfileStatisticsCallback& callback,
266 base::CancelableTaskTracker* tracker) {
267 scoped_refptr<ProfileStatisticsAggregator> aggregator =
268 new ProfileStatisticsAggregator(profile, callback, tracker);
269 }
270
271 } // namespace profiles
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698