Chromium Code Reviews| Index: chrome/browser/profiles/profile_statistics_service.cc | 
| diff --git a/chrome/browser/profiles/profile_statistics_service.cc b/chrome/browser/profiles/profile_statistics_service.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..4f7ed05145c6de235b464b8d25d57b6d33a8e39d | 
| --- /dev/null | 
| +++ b/chrome/browser/profiles/profile_statistics_service.cc | 
| @@ -0,0 +1,135 @@ | 
| +// Copyright 2015 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/profiles/profile_statistics_service.h" | 
| + | 
| +#include "base/bind.h" | 
| +#include "base/prefs/pref_service.h" | 
| +#include "base/task_runner.h" | 
| +#include "chrome/browser/bookmarks/bookmark_model_factory.h" | 
| +#include "chrome/browser/history/history_service_factory.h" | 
| +#include "chrome/browser/password_manager/password_store_factory.h" | 
| +#include "components/history/core/browser/history_service.h" | 
| +#include "components/password_manager/core/browser/password_store.h" | 
| +#include "content/public/browser/browser_thread.h" | 
| + | 
| +using content::BrowserThread; | 
| + | 
| +namespace profiles { | 
| + | 
| +ProfileStatisticsService::ProfileStatisticsService | 
| + (Profile* profile, ProfileStatisticsCallback callback) : | 
| + profile_(profile), callback_(callback), weak_factory_(this) { | 
| + init_(); | 
| +} | 
| + | 
| +void ProfileStatisticsService::init_() { | 
| + // Initiate bookmark counting (async). | 
| + bookmarks::BookmarkModel* bookmark_model = | 
| + BookmarkModelFactory::GetForProfileIfExists(profile_); | 
| + | 
| + if (bookmark_model) { | 
| + // This task does not use a database, but | 
| + // DB thread is used because most other operations in this class use it. | 
| + tracker_.PostTaskAndReplyWithResult( | 
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), | 
| 
 
Mike Lerman
2015/07/22 01:39:26
nit: indent 4 spaces whenever you line wrap.
 
lwchkg
2015/07/26 17:38:22
Acknowledged.
 
 | 
| + FROM_HERE, | 
| + base::Bind(&ProfileStatisticsService::CountURLs_, | 
| + base::Unretained(bookmark_model)), | 
| + base::Bind(&ProfileStatisticsService::StatsticsCallback_, | 
| + weak_factory_.GetWeakPtr(), | 
| + "Bookmarks")); | 
| + } else { | 
| + StatsticsCallback_("Bookmarks", 0); | 
| + } | 
| + | 
| + // Initiate history counting (async). | 
| + history::HistoryService* history_service = | 
| + HistoryServiceFactory::GetForProfileWithoutCreating(profile_); | 
| + | 
| + if (history_service) { | 
| + history_service->CountURLs( | 
| + base::Bind(&ProfileStatisticsService::StatsticsCallback_, | 
| + weak_factory_.GetWeakPtr(), | 
| + "BrowsingHistory"), | 
| + &tracker_); | 
| + } else { | 
| + StatsticsCallback_("BrowsingHistory", 0); | 
| + } | 
| + | 
| + // Initiate stored password counting (async). | 
| + scoped_refptr<password_manager::PasswordStore> password_store = | 
| + PasswordStoreFactory::GetForProfile( | 
| + profile_, ServiceAccessType::EXPLICIT_ACCESS); | 
| + if (password_store) { | 
| + // Currently this task is not cancellable. | 
| + password_store->GetCountOfLogins( | 
| + base::Bind(&ProfileStatisticsService::StatsticsCallback_, | 
| + weak_factory_.GetWeakPtr(), | 
| + "Passwords")); | 
| + } | 
| + | 
| + // Initiate preference counting (async). Post to UI thread. | 
| + tracker_.PostTaskAndReplyWithResult( | 
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(), | 
| + FROM_HERE, | 
| + base::Bind(&ProfileStatisticsService::CountPrefs_, | 
| + base::Unretained(this)), | 
| + base::Bind(&ProfileStatisticsService::StatsticsCallback_, | 
| + weak_factory_.GetWeakPtr(), | 
| + "Settings")); | 
| +} | 
| + | 
| +void ProfileStatisticsService::StatsticsCallback_(std::string category, | 
| + int count) { | 
| + profile_stats_values_.push_back(std::make_pair(category, count)); | 
| + callback_.Run(profile_stats_values_); | 
| +} | 
| + | 
| +int ProfileStatisticsService::CountURLsFromNode_( | 
| + const bookmarks::BookmarkNode* node) { | 
| + int count = 0; | 
| + if (node->is_url()) { | 
| + ++count; | 
| + } else { | 
| + for (int i = 0; i < node->child_count(); ++i) | 
| + count += CountURLsFromNode_(node->GetChild(i)); | 
| + } | 
| + return count; | 
| +} | 
| + | 
| +int ProfileStatisticsService::CountURLs_( | 
| + const bookmarks::BookmarkModel* bookmark_model) { | 
| + if (bookmark_model) | 
| 
 
Mike Lerman
2015/07/22 01:39:26
nit: use parenthesis anytime the statement block i
 
lwchkg
2015/07/26 17:38:22
Acknowledged.
 
 | 
| + return CountURLsFromNode_(bookmark_model->bookmark_bar_node()) + | 
| + CountURLsFromNode_(bookmark_model->other_node()) + | 
| + CountURLsFromNode_(bookmark_model->mobile_node()); | 
| + else | 
| + return 0; | 
| +} | 
| + | 
| +int ProfileStatisticsService::CountPrefs_() const { | 
| + const PrefService* pref_service = profile_->GetPrefs(); | 
| + | 
| + if (!pref_service) | 
| + return 0; | 
| + | 
| + scoped_ptr<base::DictionaryValue> prefs = | 
| + pref_service->GetPreferenceValuesWithoutPathExpansion(); | 
| + | 
| + int count = 0; | 
| + for (base::DictionaryValue::Iterator it(*(prefs.get())); | 
| + !it.IsAtEnd(); it.Advance()) { | 
| + const PrefService::Preference* pref = pref_service-> | 
| + FindPreference(it.key()); | 
| 
 
Mike Lerman
2015/07/22 01:39:26
indent only 4 spaces.
 
lwchkg
2015/07/26 17:38:22
Should I have "F" directly under "_"?
 
 | 
| + // Skip all dictionaries (which must be empty by the function call above). | 
| + if (it.value().GetType() != base::Value::TYPE_DICTIONARY && | 
| + pref && pref->IsUserControlled() && !pref->IsDefaultValue()) { | 
| + ++count; | 
| + } | 
| + } | 
| + return count; | 
| +} | 
| + | 
| +} // namespace profiles |