Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / sync / profile_signin_confirmation_helper.cc
blob4d5dcdac21b3d13466e614ee7824ba60ab81b520
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/extension.h"
23 #include "chrome/common/extensions/extension_set.h"
24 #include "chrome/common/extensions/sync_helper.h"
25 #include "ui/gfx/color_utils.h"
26 #include "ui/native_theme/native_theme.h"
28 // TODO(dconnelly): change VLOG to DVLOG (crbug.com/240195)
30 namespace {
32 const int kHistoryEntriesBeforeNewProfilePrompt = 10;
34 // Determines whether a profile has any typed URLs in its history.
35 class HasTypedURLsTask : public history::HistoryDBTask {
36 public:
37 HasTypedURLsTask(const base::Callback<void(bool)>& cb)
38 : has_typed_urls_(false), cb_(cb) {
41 virtual bool RunOnDBThread(history::HistoryBackend* backend,
42 history::HistoryDatabase* db) OVERRIDE {
43 history::URLRows rows;
44 backend->GetAllTypedURLs(&rows);
45 if (!rows.empty()) {
46 VLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
47 << rows.size() << " typed URLs";
48 has_typed_urls_ = true;
50 return true;
53 virtual void DoneRunOnMainThread() OVERRIDE {
54 cb_.Run(has_typed_urls_);
57 private:
58 virtual ~HasTypedURLsTask() {}
59 bool has_typed_urls_;
60 base::Callback<void(bool)> cb_;
63 bool HasBookmarks(Profile* profile) {
64 BookmarkModel* bookmarks = BookmarkModelFactory::GetForProfile(profile);
65 bool has_bookmarks = bookmarks && bookmarks->HasBookmarks();
66 if (has_bookmarks)
67 VLOG(1) << "ProfileSigninConfirmationHelper: profile contains bookmarks";
68 return has_bookmarks;
71 // Helper functions for Chrome profile signin.
72 class ProfileSigninConfirmationHelper
73 : public base::RefCounted<ProfileSigninConfirmationHelper> {
74 public:
75 ProfileSigninConfirmationHelper(
76 Profile* profile,
77 const base::Callback<void(bool)>& return_result);
78 void CheckHasHistory(int max_entries);
79 void CheckHasTypedURLs();
80 void set_pending_requests(int requests);
82 private:
83 friend class base::RefCounted<ProfileSigninConfirmationHelper>;
85 ~ProfileSigninConfirmationHelper();
87 void OnHistoryQueryResults(size_t max_entries,
88 CancelableRequestProvider::Handle handle,
89 history::QueryResults* results);
90 void ReturnResult(bool result);
92 // Weak pointer to the profile being signed-in.
93 Profile* profile_;
95 // Used for async tasks.
96 CancelableRequestConsumer request_consumer_;
98 // Keep track of how many async requests are pending.
99 int pending_requests_;
101 // Indicates whether the result has already been returned to caller.
102 bool result_returned_;
104 // Callback to pass the result back to the caller.
105 const base::Callback<void(bool)> return_result_;
107 DISALLOW_COPY_AND_ASSIGN(ProfileSigninConfirmationHelper);
110 ProfileSigninConfirmationHelper::ProfileSigninConfirmationHelper(
111 Profile* profile,
112 const base::Callback<void(bool)>& return_result)
113 : profile_(profile),
114 pending_requests_(0),
115 result_returned_(false),
116 return_result_(return_result) {
119 ProfileSigninConfirmationHelper::~ProfileSigninConfirmationHelper() {
122 void ProfileSigninConfirmationHelper::OnHistoryQueryResults(
123 size_t max_entries,
124 CancelableRequestProvider::Handle handle,
125 history::QueryResults* results) {
126 history::QueryResults owned_results;
127 results->Swap(&owned_results);
128 bool too_much_history = owned_results.size() >= max_entries;
129 if (too_much_history) {
130 VLOG(1) << "ProfileSigninConfirmationHelper: profile contains "
131 << owned_results.size() << " history entries";
133 ReturnResult(too_much_history);
136 void ProfileSigninConfirmationHelper::CheckHasHistory(int max_entries) {
137 HistoryService* service =
138 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
139 if (!service) {
140 ReturnResult(false);
141 return;
143 history::QueryOptions opts;
144 opts.max_count = max_entries;
145 service->QueryHistory(
146 string16(), opts, &request_consumer_,
147 base::Bind(&ProfileSigninConfirmationHelper::OnHistoryQueryResults,
148 this,
149 max_entries));
152 void ProfileSigninConfirmationHelper::CheckHasTypedURLs() {
153 HistoryService* service =
154 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
155 if (!service) {
156 ReturnResult(false);
157 return;
159 service->ScheduleDBTask(
160 new HasTypedURLsTask(
161 base::Bind(
162 &ProfileSigninConfirmationHelper::ReturnResult,
163 this)),
164 &request_consumer_);
167 void ProfileSigninConfirmationHelper::set_pending_requests(int requests) {
168 pending_requests_ = requests;
171 void ProfileSigninConfirmationHelper::ReturnResult(bool result) {
172 // Pass |true| into the callback as soon as one of the tasks passes a
173 // result of |true|, otherwise pass the last returned result.
174 if (!result_returned_ && (--pending_requests_ == 0 || result)) {
175 result_returned_ = true;
176 request_consumer_.CancelAllRequests();
177 return_result_.Run(result);
181 } // namespace
183 namespace ui {
185 SkColor GetSigninConfirmationPromptBarColor(SkAlpha alpha) {
186 static const SkColor kBackgroundColor =
187 ui::NativeTheme::instance()->GetSystemColor(
188 ui::NativeTheme::kColorId_DialogBackground);
189 return color_utils::BlendTowardOppositeLuminance(kBackgroundColor, alpha);
192 bool HasBeenShutdown(Profile* profile) {
193 bool has_been_shutdown = !profile->IsNewProfile();
194 if (has_been_shutdown)
195 VLOG(1) << "ProfileSigninConfirmationHelper: profile is not new";
196 return has_been_shutdown;
199 bool HasSyncedExtensions(Profile* profile) {
200 extensions::ExtensionSystem* system =
201 extensions::ExtensionSystem::Get(profile);
202 if (system && system->extension_service()) {
203 const ExtensionSet* extensions = system->extension_service()->extensions();
204 for (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 VLOG(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