Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / ui / sync / profile_signin_confirmation_helper.cc
blob6bf053536839873d13663ce6243dce23862d986a
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/ui/sync/profile_signin_confirmation_helper.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string16.h"
11 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
12 #include "chrome/browser/common/cancelable_request.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/history/history_backend.h"
15 #include "chrome/browser/history/history_db_task.h"
16 #include "chrome/browser/history/history_service.h"
17 #include "chrome/browser/history/history_service_factory.h"
18 #include "chrome/browser/history/history_types.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/extensions/extension_constants.h"
21 #include "chrome/common/extensions/sync_helper.h"
22 #include "components/bookmarks/browser/bookmark_model.h"
23 #include "extensions/browser/extension_system.h"
24 #include "extensions/common/extension.h"
25 #include "extensions/common/extension_set.h"
26 #include "ui/gfx/color_utils.h"
27 #include "ui/native_theme/native_theme.h"
29 namespace {
31 const int kHistoryEntriesBeforeNewProfilePrompt = 10;
33 // Determines whether a profile has any typed URLs in its history.
34 class HasTypedURLsTask : public history::HistoryDBTask {
35 public:
36 HasTypedURLsTask(const base::Callback<void(bool)>& cb)
37 : has_typed_urls_(false), cb_(cb) {
40 virtual bool RunOnDBThread(history::HistoryBackend* backend,
41 history::HistoryDatabase* db) OVERRIDE {
42 history::URLRows rows;
43 backend->GetAllTypedURLs(&rows);
44 if (!rows.empty()) {
45 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
46 << rows.size() << " typed URLs";
47 has_typed_urls_ = true;
49 return true;
52 virtual void DoneRunOnMainThread() OVERRIDE {
53 cb_.Run(has_typed_urls_);
56 private:
57 virtual ~HasTypedURLsTask() {}
58 bool has_typed_urls_;
59 base::Callback<void(bool)> cb_;
62 bool HasBookmarks(Profile* profile) {
63 BookmarkModel* bookmarks = BookmarkModelFactory::GetForProfile(profile);
64 bool has_bookmarks = bookmarks && bookmarks->HasBookmarks();
65 if (has_bookmarks)
66 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains bookmarks";
67 return has_bookmarks;
70 // Helper functions for Chrome profile signin.
71 class ProfileSigninConfirmationHelper
72 : public base::RefCounted<ProfileSigninConfirmationHelper> {
73 public:
74 ProfileSigninConfirmationHelper(
75 Profile* profile,
76 const base::Callback<void(bool)>& return_result);
77 void CheckHasHistory(int max_entries);
78 void CheckHasTypedURLs();
79 void set_pending_requests(int requests);
81 private:
82 friend class base::RefCounted<ProfileSigninConfirmationHelper>;
84 ~ProfileSigninConfirmationHelper();
86 void OnHistoryQueryResults(size_t max_entries,
87 CancelableRequestProvider::Handle handle,
88 history::QueryResults* results);
89 void ReturnResult(bool result);
91 // Weak pointer to the profile being signed-in.
92 Profile* profile_;
94 // Used for async tasks.
95 CancelableRequestConsumer request_consumer_;
97 // Keep track of how many async requests are pending.
98 int pending_requests_;
100 // Indicates whether the result has already been returned to caller.
101 bool result_returned_;
103 // Callback to pass the result back to the caller.
104 const base::Callback<void(bool)> return_result_;
106 DISALLOW_COPY_AND_ASSIGN(ProfileSigninConfirmationHelper);
109 ProfileSigninConfirmationHelper::ProfileSigninConfirmationHelper(
110 Profile* profile,
111 const base::Callback<void(bool)>& return_result)
112 : profile_(profile),
113 pending_requests_(0),
114 result_returned_(false),
115 return_result_(return_result) {
118 ProfileSigninConfirmationHelper::~ProfileSigninConfirmationHelper() {
121 void ProfileSigninConfirmationHelper::OnHistoryQueryResults(
122 size_t max_entries,
123 CancelableRequestProvider::Handle handle,
124 history::QueryResults* results) {
125 history::QueryResults owned_results;
126 results->Swap(&owned_results);
127 bool too_much_history = owned_results.size() >= max_entries;
128 if (too_much_history) {
129 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
130 << owned_results.size() << " history entries";
132 ReturnResult(too_much_history);
135 void ProfileSigninConfirmationHelper::CheckHasHistory(int max_entries) {
136 HistoryService* service =
137 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
138 if (!service) {
139 ReturnResult(false);
140 return;
142 history::QueryOptions opts;
143 opts.max_count = max_entries;
144 service->QueryHistory(
145 base::string16(), opts, &request_consumer_,
146 base::Bind(&ProfileSigninConfirmationHelper::OnHistoryQueryResults,
147 this,
148 max_entries));
151 void ProfileSigninConfirmationHelper::CheckHasTypedURLs() {
152 HistoryService* service =
153 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
154 if (!service) {
155 ReturnResult(false);
156 return;
158 service->ScheduleDBTask(
159 new HasTypedURLsTask(
160 base::Bind(
161 &ProfileSigninConfirmationHelper::ReturnResult,
162 this)),
163 &request_consumer_);
166 void ProfileSigninConfirmationHelper::set_pending_requests(int requests) {
167 pending_requests_ = requests;
170 void ProfileSigninConfirmationHelper::ReturnResult(bool result) {
171 // Pass |true| into the callback as soon as one of the tasks passes a
172 // result of |true|, otherwise pass the last returned result.
173 if (!result_returned_ && (--pending_requests_ == 0 || result)) {
174 result_returned_ = true;
175 request_consumer_.CancelAllRequests();
176 return_result_.Run(result);
180 } // namespace
182 namespace ui {
184 SkColor GetSigninConfirmationPromptBarColor(SkAlpha alpha) {
185 static const SkColor kBackgroundColor =
186 ui::NativeTheme::instance()->GetSystemColor(
187 ui::NativeTheme::kColorId_DialogBackground);
188 return color_utils::BlendTowardOppositeLuminance(kBackgroundColor, alpha);
191 bool HasBeenShutdown(Profile* profile) {
192 bool has_been_shutdown = !profile->IsNewProfile();
193 if (has_been_shutdown)
194 DVLOG(1) << "ProfileSigninConfirmationHelper: profile is not new";
195 return has_been_shutdown;
198 bool HasSyncedExtensions(Profile* profile) {
199 extensions::ExtensionSystem* system =
200 extensions::ExtensionSystem::Get(profile);
201 if (system && system->extension_service()) {
202 const extensions::ExtensionSet* extensions =
203 system->extension_service()->extensions();
204 for (extensions::ExtensionSet::const_iterator iter = extensions->begin();
205 iter != extensions->end(); ++iter) {
206 // The webstore is synced so that it stays put on the new tab
207 // page, but since it's installed by default we don't want to
208 // consider it when determining if the profile is dirty.
209 if (extensions::sync_helper::IsSyncable(iter->get()) &&
210 (*iter)->id() != extension_misc::kWebStoreAppId &&
211 (*iter)->id() != extension_misc::kChromeAppId) {
212 DVLOG(1) << "ProfileSigninConfirmationHelper: "
213 << "profile contains a synced extension: " << (*iter)->id();
214 return true;
218 return false;
221 void CheckShouldPromptForNewProfile(
222 Profile* profile,
223 const base::Callback<void(bool)>& return_result) {
224 if (HasBeenShutdown(profile) ||
225 HasBookmarks(profile) ||
226 HasSyncedExtensions(profile)) {
227 return_result.Run(true);
228 return;
230 // Fire asynchronous queries for profile data.
231 scoped_refptr<ProfileSigninConfirmationHelper> helper =
232 new ProfileSigninConfirmationHelper(profile, return_result);
233 const int requests = 2;
234 helper->set_pending_requests(requests);
235 helper->CheckHasHistory(kHistoryEntriesBeforeNewProfilePrompt);
236 helper->CheckHasTypedURLs();
239 } // namespace ui