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

Unified Diff: chrome/browser/profiles/profile_statistics.cc

Issue 1579433002: Make profile statistics tasks inspectable by tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renamed ProfileAttributesStorage related functions in profile_statistics.* Created 4 years, 9 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/profiles/profile_statistics.cc
diff --git a/chrome/browser/profiles/profile_statistics.cc b/chrome/browser/profiles/profile_statistics.cc
index a1d73f034b58cbdd785465aa890f066b84b91691..8cfa7e72cc44215d11b093dc1b6603b3ada4ed66 100644
--- a/chrome/browser/profiles/profile_statistics.cc
+++ b/chrome/browser/profiles/profile_statistics.cc
@@ -4,379 +4,89 @@
#include "chrome/browser/profiles/profile_statistics.h"
-#include <set>
-
#include "base/bind.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/task_runner.h"
-#include "base/time/time.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/password_manager/password_store_factory.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
-#include "components/bookmarks/browser/bookmark_model.h"
-#include "components/bookmarks/browser/bookmark_model_observer.h"
-#include "components/history/core/browser/history_service.h"
-#include "components/password_manager/core/browser/password_store.h"
-#include "components/password_manager/core/browser/password_store_consumer.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace {
-
-struct ProfileStatValue {
- int count;
- bool success; // false means the statistics failed to load
-};
+#include "chrome/browser/profiles/profile_statistics_aggregator.h"
-int CountBookmarksFromNode(const bookmarks::BookmarkNode* node) {
- int count = 0;
- if (node->is_url()) {
- ++count;
- } else {
- for (int i = 0; i < node->child_count(); ++i)
- count += CountBookmarksFromNode(node->GetChild(i));
- }
- return count;
+ProfileStatistics::ProfileStatistics(Profile* profile)
+ : profile_(profile), aggregator_(nullptr), weak_ptr_factory_(this) {
}
-class ProfileStatisticsAggregator
- : public base::RefCountedThreadSafe<ProfileStatisticsAggregator> {
- // This class is used internally by GetProfileStatistics and
- // StoreProfileStatisticsToCache.
- //
- // The class collects statistical information about the profile and returns
- // the information via a callback function. Currently bookmarks, history,
- // logins and preferences are counted.
- //
- // The class is RefCounted because this is needed for CancelableTaskTracker
- // to function properly. Once all tasks are run (or cancelled) the instance is
- // automatically destructed.
-
- public:
- ProfileStatisticsAggregator(Profile* profile,
- const profiles::ProfileStatisticsCallback& callback,
- base::CancelableTaskTracker* tracker);
-
- private:
- friend class base::RefCountedThreadSafe<ProfileStatisticsAggregator>;
- ~ProfileStatisticsAggregator() {}
-
- void Init();
-
- // Callback functions
- // Normal callback. Appends result to |profile_category_stats_|, and then call
- // the external callback. All other callbacks call this function.
- void StatisticsCallback(const char* category, ProfileStatValue result);
- // Callback for reporting success.
- void StatisticsCallbackSuccess(const char* category, int count);
- // Callback for reporting failure.
- void StatisticsCallbackFailure(const char* category);
- // Callback for history.
- void StatisticsCallbackHistory(history::HistoryCountResult result);
-
- // Bookmark counting.
- void WaitOrCountBookmarks();
- void CountBookmarks(bookmarks::BookmarkModel* bookmark_model);
-
- class BookmarkModelHelper
- : public bookmarks::BookmarkModelObserver {
- public:
- explicit BookmarkModelHelper(ProfileStatisticsAggregator* parent)
- : parent_(parent) {}
-
- void BookmarkModelLoaded(bookmarks::BookmarkModel* model,
- bool ids_reassigned)
- override {
- // Remove observer before release, otherwise it may become a dangling
- // reference.
- model->RemoveObserver(this);
- parent_->CountBookmarks(model);
- parent_->Release();
- }
-
- void BookmarkNodeMoved(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* old_parent,
- int old_index,
- const bookmarks::BookmarkNode* new_parent,
- int new_index) override {}
-
- void BookmarkNodeAdded(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* parent,
- int index) override {}
-
- void BookmarkNodeRemoved(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* parent,
- int old_index, const bookmarks::BookmarkNode* node,
- const std::set<GURL>& no_longer_bookmarked) override {}
-
- void BookmarkNodeChanged(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* node) override {}
-
- void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* node) override {}
-
- void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* node) override {}
-
- void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model,
- const std::set<GURL>& removed_urls) override {}
-
- private:
- ProfileStatisticsAggregator* parent_ = nullptr;
- };
-
- // Password counting
- class PasswordStoreConsumerHelper
- : public password_manager::PasswordStoreConsumer {
- public:
- explicit PasswordStoreConsumerHelper(ProfileStatisticsAggregator* parent)
- : parent_(parent) {}
-
- void OnGetPasswordStoreResults(
- ScopedVector<autofill::PasswordForm> results) override {
- parent_->StatisticsCallbackSuccess(profiles::kProfileStatisticsPasswords,
- results.size());
- }
-
- private:
- ProfileStatisticsAggregator* parent_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(PasswordStoreConsumerHelper);
- };
-
- // Preference counting.
- ProfileStatValue CountPrefs() const;
-
- Profile* profile_;
- profiles::ProfileCategoryStats profile_category_stats_;
-
- // Callback function to be called when results arrive. Will be called
- // multiple times (once for each statistics).
- const profiles::ProfileStatisticsCallback callback_;
-
- base::CancelableTaskTracker* tracker_;
- scoped_ptr<base::CancelableTaskTracker> default_tracker_;
-
- // Bookmark counting
- scoped_ptr<BookmarkModelHelper> bookmark_model_helper_;
-
- // Password counting.
- PasswordStoreConsumerHelper password_store_consumer_helper_;
-
- DISALLOW_COPY_AND_ASSIGN(ProfileStatisticsAggregator);
-};
-
-ProfileStatisticsAggregator::ProfileStatisticsAggregator(
- Profile* profile,
- const profiles::ProfileStatisticsCallback& callback,
- base::CancelableTaskTracker* tracker)
- : profile_(profile),
- callback_(callback),
- tracker_(tracker),
- password_store_consumer_helper_(this) {
- if (!tracker_) {
- default_tracker_.reset(new base::CancelableTaskTracker);
- tracker_ = default_tracker_.get();
- }
- Init();
+ProfileStatistics::~ProfileStatistics() {
}
-void ProfileStatisticsAggregator::Init() {
- DCHECK(profile_);
-
- // Initiate bookmark counting (async). Post to UI thread.
- tracker_->PostTask(
- content::BrowserThread::GetMessageLoopProxyForThread(
- content::BrowserThread::UI).get(),
- FROM_HERE,
- base::Bind(&ProfileStatisticsAggregator::WaitOrCountBookmarks, this));
-
- // Initiate history counting (async).
- history::HistoryService* history_service =
- HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
-
- if (history_service) {
- history_service->GetHistoryCount(
- base::Time(),
- base::Time::Max(),
- base::Bind(&ProfileStatisticsAggregator::StatisticsCallbackHistory,
- this),
- tracker_);
- } else {
- StatisticsCallbackFailure(profiles::kProfileStatisticsBrowsingHistory);
- }
+void ProfileStatistics::GatherStatistics(
+ const profiles::ProfileStatisticsCallback& callback) {
+ // IsValidProfile() can be false in unit tests.
+ if (!g_browser_process->profile_manager()->IsValidProfile(profile_))
+ return;
+ DCHECK(!profile_->IsOffTheRecord() && !profile_->IsSystemProfile());
- // Initiate stored password counting (async).
- // TODO(anthonyvd): make password task cancellable.
- scoped_refptr<password_manager::PasswordStore> password_store =
- PasswordStoreFactory::GetForProfile(
- profile_, ServiceAccessType::EXPLICIT_ACCESS);
- if (password_store) {
- password_store->GetAutofillableLogins(&password_store_consumer_helper_);
+ if (HasAggregator()) {
+ GetAggregator()->AddCallbackAndStartAggregator(callback);
} else {
- StatisticsCallbackFailure(profiles::kProfileStatisticsPasswords);
- }
-
- // Initiate preference counting (async). Post to UI thread.
- tracker_->PostTaskAndReplyWithResult(
- content::BrowserThread::GetMessageLoopProxyForThread(
- content::BrowserThread::UI).get(),
- FROM_HERE,
- base::Bind(&ProfileStatisticsAggregator::CountPrefs, this),
- base::Bind(&ProfileStatisticsAggregator::StatisticsCallback,
- this, profiles::kProfileStatisticsSettings));
-}
-
-void ProfileStatisticsAggregator::StatisticsCallback(
- const char* category, ProfileStatValue result) {
- profiles::ProfileCategoryStat datum;
- datum.category = category;
- datum.count = result.count;
- datum.success = result.success;
- profile_category_stats_.push_back(datum);
- if (!callback_.is_null())
- callback_.Run(profile_category_stats_);
-
- if (result.success) {
- profiles::SetProfileStatisticsInCache(profile_->GetPath(), datum.category,
- result.count);
+ // The statistics task may outlive ProfileStatistics in unit tests, so a
+ // weak pointer is used for the callback.
+ scoped_refptr<ProfileStatisticsAggregator> aggregator =
+ new ProfileStatisticsAggregator(
+ profile_,
+ callback,
+ base::Bind(&ProfileStatistics::DeregisterAggregator,
+ weak_ptr_factory_.GetWeakPtr()));
+ RegisterAggregator(aggregator.get());
}
}
-void ProfileStatisticsAggregator::StatisticsCallbackSuccess(
- const char* category, int count) {
- ProfileStatValue result;
- result.count = count;
- result.success = true;
- StatisticsCallback(category, result);
+bool ProfileStatistics::HasAggregator() const {
+ return aggregator_ != nullptr;
}
-void ProfileStatisticsAggregator::StatisticsCallbackFailure(
- const char* category) {
- ProfileStatValue result;
- result.count = 0;
- result.success = false;
- StatisticsCallback(category, result);
+ProfileStatisticsAggregator* ProfileStatistics::GetAggregator() const {
+ return aggregator_;
}
-void ProfileStatisticsAggregator::StatisticsCallbackHistory(
- history::HistoryCountResult result) {
- ProfileStatValue result_converted;
- result_converted.count = result.count;
- result_converted.success = result.success;
- StatisticsCallback(profiles::kProfileStatisticsBrowsingHistory,
- result_converted);
+void ProfileStatistics::RegisterAggregator(
+ ProfileStatisticsAggregator* aggregator) {
+ aggregator_ = aggregator;
}
-void ProfileStatisticsAggregator::CountBookmarks(
- bookmarks::BookmarkModel* bookmark_model) {
- int count = CountBookmarksFromNode(bookmark_model->bookmark_bar_node()) +
- CountBookmarksFromNode(bookmark_model->other_node()) +
- CountBookmarksFromNode(bookmark_model->mobile_node());
-
- StatisticsCallbackSuccess(profiles::kProfileStatisticsBookmarks, count);
+void ProfileStatistics::DeregisterAggregator() {
+ aggregator_ = nullptr;
}
-void ProfileStatisticsAggregator::WaitOrCountBookmarks() {
- bookmarks::BookmarkModel* bookmark_model =
- BookmarkModelFactory::GetForProfileIfExists(profile_);
-
- if (bookmark_model) {
- if (bookmark_model->loaded()) {
- CountBookmarks(bookmark_model);
- } else {
- AddRef();
- bookmark_model_helper_.reset(new BookmarkModelHelper(this));
- bookmark_model->AddObserver(bookmark_model_helper_.get());
- }
- } else {
- StatisticsCallbackFailure(profiles::kProfileStatisticsBookmarks);
- }
-}
-
-ProfileStatValue ProfileStatisticsAggregator::CountPrefs() const {
- const PrefService* pref_service = profile_->GetPrefs();
-
- ProfileStatValue result;
- if (pref_service) {
- 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());
- // 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;
- }
- }
-
- result.count = count;
- result.success = true;
- } else {
- result.count = 0;
- result.success = false;
- }
- return result;
-}
-
-} // namespace
-
-namespace profiles {
-
-// Constants for the categories in ProfileCategoryStats
-const char kProfileStatisticsBrowsingHistory[] = "BrowsingHistory";
-const char kProfileStatisticsPasswords[] = "Passwords";
-const char kProfileStatisticsBookmarks[] = "Bookmarks";
-const char kProfileStatisticsSettings[] = "Settings";
-
-void GatherProfileStatistics(Profile* profile,
- const ProfileStatisticsCallback& callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK(profile);
- if (profile->IsOffTheRecord() || profile->IsSystemProfile()) {
- NOTREACHED();
- return;
- }
-
- scoped_refptr<ProfileStatisticsAggregator> aggregator =
- new ProfileStatisticsAggregator(profile, callback, tracker);
-}
-
-ProfileCategoryStats GetProfileStatisticsFromCache(
- const base::FilePath& profile_path) {
+// static
+profiles::ProfileCategoryStats
+ ProfileStatistics::GetProfileStatisticsFromAttributesStorage(
+ const base::FilePath& profile_path) {
ProfileAttributesEntry* entry = nullptr;
bool has_entry = g_browser_process->profile_manager()->
GetProfileAttributesStorage().
GetProfileAttributesWithPath(profile_path, &entry);
- ProfileCategoryStats stats;
- ProfileCategoryStat stat;
+ profiles::ProfileCategoryStats stats;
+ profiles::ProfileCategoryStat stat;
- stat.category = kProfileStatisticsBrowsingHistory;
+ stat.category = profiles::kProfileStatisticsBrowsingHistory;
stat.success = has_entry ? entry->HasStatsBrowsingHistory() : false;
stat.count = stat.success ? entry->GetStatsBrowsingHistory() : 0;
stats.push_back(stat);
- stat.category = kProfileStatisticsPasswords;
+ stat.category = profiles::kProfileStatisticsPasswords;
stat.success = has_entry ? entry->HasStatsPasswords() : false;
stat.count = stat.success ? entry->GetStatsPasswords() : 0;
stats.push_back(stat);
- stat.category = kProfileStatisticsBookmarks;
+ stat.category = profiles::kProfileStatisticsBookmarks;
stat.success = has_entry ? entry->HasStatsBookmarks() : false;
stat.count = stat.success ? entry->GetStatsBookmarks() : 0;
stats.push_back(stat);
- stat.category = kProfileStatisticsSettings;
+ stat.category = profiles::kProfileStatisticsSettings;
stat.success = has_entry ? entry->HasStatsSettings() : false;
stat.count = stat.success ? entry->GetStatsSettings() : 0;
stats.push_back(stat);
@@ -384,33 +94,33 @@ ProfileCategoryStats GetProfileStatisticsFromCache(
return stats;
}
-void SetProfileStatisticsInCache(const base::FilePath& profile_path,
- const std::string& category, int count) {
- // If local_state() is null, profile_manager() will seg-fault.
- if (!g_browser_process || !g_browser_process->local_state())
- return;
-
- // profile_manager() may return a null pointer.
+// static
+void ProfileStatistics::SetProfileStatisticsToAttributesStorage(
+ const base::FilePath& profile_path,
+ const std::string& category,
+ int count) {
+ // |profile_manager()| may return a null pointer.
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (!profile_manager)
return;
ProfileAttributesEntry* entry = nullptr;
if (!profile_manager->GetProfileAttributesStorage().
- GetProfileAttributesWithPath(profile_path, &entry))
+ GetProfileAttributesWithPath(profile_path, &entry)) {
+ // It is possible to have the profile attributes entry absent, e.g. the
+ // profile is scheduled for deletion during the async statistics task.
return;
+ }
- if (category == kProfileStatisticsBrowsingHistory) {
+ if (category == profiles::kProfileStatisticsBrowsingHistory) {
entry->SetStatsBrowsingHistory(count);
- } else if (category == kProfileStatisticsPasswords) {
+ } else if (category == profiles::kProfileStatisticsPasswords) {
entry->SetStatsPasswords(count);
- } else if (category == kProfileStatisticsBookmarks) {
+ } else if (category == profiles::kProfileStatisticsBookmarks) {
entry->SetStatsBookmarks(count);
- } else if (category == kProfileStatisticsSettings) {
+ } else if (category == profiles::kProfileStatisticsSettings) {
entry->SetStatsSettings(count);
} else {
NOTREACHED();
}
}
-
-} // namespace profiles
« no previous file with comments | « chrome/browser/profiles/profile_statistics.h ('k') | chrome/browser/profiles/profile_statistics_aggregator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698