Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / sync / profile_signin_confirmation_helper.cc
blob57fc1018f4eddff2f034d33f6f22e047fbd7ed5e
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.h"
12 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
13 #include "chrome/browser/common/cancelable_request.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extension_system.h"
16 #include "chrome/browser/history/history_backend.h"
17 #include "chrome/browser/history/history_db_task.h"
18 #include "chrome/browser/history/history_service.h"
19 #include "chrome/browser/history/history_service_factory.h"
20 #include "chrome/browser/history/history_types.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/common/extensions/sync_helper.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_set.h"
25 #include "ui/gfx/color_utils.h"
26 #include "ui/native_theme/native_theme.h"
28 namespace {
30 const int kHistoryEntriesBeforeNewProfilePrompt = 10;
32 // Determines whether a profile has any typed URLs in its history.
33 class HasTypedURLsTask : public history::HistoryDBTask {
34 public:
35 HasTypedURLsTask(const base::Callback<void(bool)>& cb)
36 : has_typed_urls_(false), cb_(cb) {
39 virtual bool RunOnDBThread(history::HistoryBackend* backend,
40 history::HistoryDatabase* db) OVERRIDE {
41 history::URLRows rows;
42 backend->GetAllTypedURLs(&rows);
43 if (!rows.empty()) {
44 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
45 << rows.size() << " typed URLs";
46 has_typed_urls_ = true;
48 return true;
51 virtual void DoneRunOnMainThread() OVERRIDE {
52 cb_.Run(has_typed_urls_);
55 private:
56 virtual ~HasTypedURLsTask() {}
57 bool has_typed_urls_;
58 base::Callback<void(bool)> cb_;
61 bool HasBookmarks(Profile* profile) {
62 BookmarkModel* bookmarks = BookmarkModelFactory::GetForProfile(profile);
63 bool has_bookmarks = bookmarks && bookmarks->HasBookmarks();
64 if (has_bookmarks)
65 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains bookmarks";
66 return has_bookmarks;
69 // Helper functions for Chrome profile signin.
70 class ProfileSigninConfirmationHelper
71 : public base::RefCounted<ProfileSigninConfirmationHelper> {
72 public:
73 ProfileSigninConfirmationHelper(
74 Profile* profile,
75 const base::Callback<void(bool)>& return_result);
76 void CheckHasHistory(int max_entries);
77 void CheckHasTypedURLs();
78 void set_pending_requests(int requests);
80 private:
81 friend class base::RefCounted<ProfileSigninConfirmationHelper>;
83 ~ProfileSigninConfirmationHelper();
85 void OnHistoryQueryResults(size_t max_entries,
86 CancelableRequestProvider::Handle handle,
87 history::QueryResults* results);
88 void ReturnResult(bool result);
90 // Weak pointer to the profile being signed-in.
91 Profile* profile_;
93 // Used for async tasks.
94 CancelableRequestConsumer request_consumer_;
96 // Keep track of how many async requests are pending.
97 int pending_requests_;
99 // Indicates whether the result has already been returned to caller.
100 bool result_returned_;
102 // Callback to pass the result back to the caller.
103 const base::Callback<void(bool)> return_result_;
105 DISALLOW_COPY_AND_ASSIGN(ProfileSigninConfirmationHelper);
108 ProfileSigninConfirmationHelper::ProfileSigninConfirmationHelper(
109 Profile* profile,
110 const base::Callback<void(bool)>& return_result)
111 : profile_(profile),
112 pending_requests_(0),
113 result_returned_(false),
114 return_result_(return_result) {
117 ProfileSigninConfirmationHelper::~ProfileSigninConfirmationHelper() {
120 void ProfileSigninConfirmationHelper::OnHistoryQueryResults(
121 size_t max_entries,
122 CancelableRequestProvider::Handle handle,
123 history::QueryResults* results) {
124 history::QueryResults owned_results;
125 results->Swap(&owned_results);
126 bool too_much_history = owned_results.size() >= max_entries;
127 if (too_much_history) {
128 DVLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
129 << owned_results.size() << " history entries";
131 ReturnResult(too_much_history);
134 void ProfileSigninConfirmationHelper::CheckHasHistory(int max_entries) {
135 HistoryService* service =
136 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
137 if (!service) {
138 ReturnResult(false);
139 return;
141 history::QueryOptions opts;
142 opts.max_count = max_entries;
143 service->QueryHistory(
144 base::string16(), opts, &request_consumer_,
145 base::Bind(&ProfileSigninConfirmationHelper::OnHistoryQueryResults,
146 this,
147 max_entries));
150 void ProfileSigninConfirmationHelper::CheckHasTypedURLs() {
151 HistoryService* service =
152 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
153 if (!service) {
154 ReturnResult(false);
155 return;
157 service->ScheduleDBTask(
158 new HasTypedURLsTask(
159 base::Bind(
160 &ProfileSigninConfirmationHelper::ReturnResult,
161 this)),
162 &request_consumer_);
165 void ProfileSigninConfirmationHelper::set_pending_requests(int requests) {
166 pending_requests_ = requests;
169 void ProfileSigninConfirmationHelper::ReturnResult(bool result) {
170 // Pass |true| into the callback as soon as one of the tasks passes a
171 // result of |true|, otherwise pass the last returned result.
172 if (!result_returned_ && (--pending_requests_ == 0 || result)) {
173 result_returned_ = true;
174 request_consumer_.CancelAllRequests();
175 return_result_.Run(result);
179 } // namespace
181 namespace ui {
183 SkColor GetSigninConfirmationPromptBarColor(SkAlpha alpha) {
184 static const SkColor kBackgroundColor =
185 ui::NativeTheme::instance()->GetSystemColor(
186 ui::NativeTheme::kColorId_DialogBackground);
187 return color_utils::BlendTowardOppositeLuminance(kBackgroundColor, alpha);
190 bool HasBeenShutdown(Profile* profile) {
191 bool has_been_shutdown = !profile->IsNewProfile();
192 if (has_been_shutdown)
193 DVLOG(1) << "ProfileSigninConfirmationHelper: profile is not new";
194 return has_been_shutdown;
197 bool HasSyncedExtensions(Profile* profile) {
198 extensions::ExtensionSystem* system =
199 extensions::ExtensionSystem::Get(profile);
200 if (system && system->extension_service()) {
201 const extensions::ExtensionSet* extensions =
202 system->extension_service()->extensions();
203 for (extensions::ExtensionSet::const_iterator iter = extensions->begin();
204 iter != extensions->end(); ++iter) {
205 // The webstore is synced so that it stays put on the new tab
206 // page, but since it's installed by default we don't want to
207 // consider it when determining if the profile is dirty.
208 if (extensions::sync_helper::IsSyncable(iter->get()) &&
209 (*iter)->id() != extension_misc::kWebStoreAppId &&
210 (*iter)->id() != extension_misc::kChromeAppId) {
211 DVLOG(1) << "ProfileSigninConfirmationHelper: "
212 << "profile contains a synced extension: " << (*iter)->id();
213 return true;
217 return false;
220 void CheckShouldPromptForNewProfile(
221 Profile* profile,
222 const base::Callback<void(bool)>& return_result) {
223 if (HasBeenShutdown(profile) ||
224 HasBookmarks(profile) ||
225 HasSyncedExtensions(profile)) {
226 return_result.Run(true);
227 return;
229 // Fire asynchronous queries for profile data.
230 scoped_refptr<ProfileSigninConfirmationHelper> helper =
231 new ProfileSigninConfirmationHelper(profile, return_result);
232 const int requests = 2;
233 helper->set_pending_requests(requests);
234 helper->CheckHasHistory(kHistoryEntriesBeforeNewProfilePrompt);
235 helper->CheckHasTypedURLs();
238 } // namespace ui