Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / signin / chrome_signin_client.cc
blob6a9de6c4e9b71097f53771e24e1d20602bd7a6d3
1 // Copyright 2014 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/signin/chrome_signin_client.h"
7 #include "base/command_line.h"
8 #include "base/guid.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/content_settings/cookie_settings.h"
13 #include "chrome/browser/net/chrome_cookie_notification_details.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/signin/local_auth.h"
17 #include "chrome/browser/webdata/web_data_service_factory.h"
18 #include "chrome/common/chrome_version_info.h"
19 #include "components/metrics/metrics_service.h"
20 #include "components/signin/core/common/profile_management_switches.h"
21 #include "components/signin/core/common/signin_pref_names.h"
22 #include "components/signin/core/common/signin_switches.h"
23 #include "content/public/browser/notification_details.h"
24 #include "content/public/browser/notification_source.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/common/child_process_host.h"
27 #include "url/gurl.h"
29 #if defined(ENABLE_MANAGED_USERS)
30 #include "chrome/browser/supervised_user/supervised_user_constants.h"
31 #endif
33 #if defined(OS_CHROMEOS)
34 #include "components/user_manager/user_manager.h"
35 #endif
37 #if !defined(OS_ANDROID)
38 #include "chrome/browser/first_run/first_run.h"
39 #endif
41 using content::ChildProcessHost;
42 using content::RenderProcessHost;
44 namespace {
46 const char kGoogleAccountsUrl[] = "https://accounts.google.com";
48 } // namespace
50 ChromeSigninClient::ChromeSigninClient(Profile* profile)
51 : profile_(profile), signin_host_id_(ChildProcessHost::kInvalidUniqueID) {
52 callbacks_.set_removal_callback(
53 base::Bind(&ChromeSigninClient::UnregisterForCookieChangedNotification,
54 base::Unretained(this)));
57 ChromeSigninClient::~ChromeSigninClient() {
58 UnregisterForCookieChangedNotification();
60 std::set<RenderProcessHost*>::iterator i;
61 for (i = signin_hosts_observed_.begin(); i != signin_hosts_observed_.end();
62 ++i) {
63 (*i)->RemoveObserver(this);
67 // static
68 bool ChromeSigninClient::ProfileAllowsSigninCookies(Profile* profile) {
69 CookieSettings* cookie_settings =
70 CookieSettings::Factory::GetForProfile(profile).get();
71 return SettingsAllowSigninCookies(cookie_settings);
74 // static
75 bool ChromeSigninClient::SettingsAllowSigninCookies(
76 CookieSettings* cookie_settings) {
77 return cookie_settings &&
78 cookie_settings->IsSettingCookieAllowed(GURL(kGoogleAccountsUrl),
79 GURL(kGoogleAccountsUrl));
82 void ChromeSigninClient::SetSigninProcess(int process_id) {
83 if (process_id == signin_host_id_)
84 return;
85 DLOG_IF(WARNING, signin_host_id_ != ChildProcessHost::kInvalidUniqueID)
86 << "Replacing in-use signin process.";
87 signin_host_id_ = process_id;
88 RenderProcessHost* host = RenderProcessHost::FromID(process_id);
89 DCHECK(host);
90 host->AddObserver(this);
91 signin_hosts_observed_.insert(host);
94 void ChromeSigninClient::ClearSigninProcess() {
95 signin_host_id_ = ChildProcessHost::kInvalidUniqueID;
98 bool ChromeSigninClient::IsSigninProcess(int process_id) const {
99 return process_id != ChildProcessHost::kInvalidUniqueID &&
100 process_id == signin_host_id_;
103 bool ChromeSigninClient::HasSigninProcess() const {
104 return signin_host_id_ != ChildProcessHost::kInvalidUniqueID;
107 void ChromeSigninClient::RenderProcessHostDestroyed(RenderProcessHost* host) {
108 // It's possible we're listening to a "stale" renderer because it was replaced
109 // with a new process by process-per-site. In either case, stop observing it,
110 // but only reset signin_host_id_ tracking if this was from the current signin
111 // process.
112 signin_hosts_observed_.erase(host);
113 if (signin_host_id_ == host->GetID())
114 signin_host_id_ = ChildProcessHost::kInvalidUniqueID;
117 PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); }
119 scoped_refptr<TokenWebData> ChromeSigninClient::GetDatabase() {
120 return WebDataServiceFactory::GetTokenWebDataForProfile(
121 profile_, Profile::EXPLICIT_ACCESS);
124 bool ChromeSigninClient::CanRevokeCredentials() {
125 #if defined(OS_CHROMEOS)
126 // UserManager may not exist in unit_tests.
127 if (user_manager::UserManager::IsInitialized() &&
128 user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) {
129 // Don't allow revoking credentials for Chrome OS supervised users.
130 // See http://crbug.com/332032
131 LOG(ERROR) << "Attempt to revoke supervised user refresh "
132 << "token detected, ignoring.";
133 return false;
135 #else
136 // Don't allow revoking credentials for supervised users.
137 // See http://crbug.com/332032
138 if (profile_->IsSupervised()) {
139 LOG(ERROR) << "Attempt to revoke supervised user refresh "
140 << "token detected, ignoring.";
141 return false;
143 #endif
144 return true;
147 std::string ChromeSigninClient::GetSigninScopedDeviceId() {
148 if (CommandLine::ForCurrentProcess()->HasSwitch(
149 switches::kDisableSigninScopedDeviceId)) {
150 return std::string();
153 std::string signin_scoped_device_id =
154 GetPrefs()->GetString(prefs::kGoogleServicesSigninScopedDeviceId);
155 if (signin_scoped_device_id.empty()) {
156 // If device_id doesn't exist then generate new and save in prefs.
157 signin_scoped_device_id = base::GenerateGUID();
158 DCHECK(!signin_scoped_device_id.empty());
159 GetPrefs()->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
160 signin_scoped_device_id);
162 return signin_scoped_device_id;
165 void ChromeSigninClient::OnSignedOut() {
166 GetPrefs()->ClearPref(prefs::kGoogleServicesSigninScopedDeviceId);
167 ProfileInfoCache& cache =
168 g_browser_process->profile_manager()->GetProfileInfoCache();
169 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
170 cache.SetLocalAuthCredentialsOfProfileAtIndex(index, std::string());
173 net::URLRequestContextGetter* ChromeSigninClient::GetURLRequestContext() {
174 return profile_->GetRequestContext();
177 bool ChromeSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() {
178 // If inline sign in is enabled, but account consistency is not, the user's
179 // credentials should be merge into the cookie jar.
180 return !switches::IsEnableWebBasedSignin() &&
181 !switches::IsEnableAccountConsistency();
184 std::string ChromeSigninClient::GetProductVersion() {
185 chrome::VersionInfo chrome_version;
186 return chrome_version.CreateVersionString();
189 bool ChromeSigninClient::IsFirstRun() const {
190 #if defined(OS_ANDROID)
191 return false;
192 #else
193 return first_run::IsChromeFirstRun();
194 #endif
197 base::Time ChromeSigninClient::GetInstallDate() {
198 return base::Time::FromTimeT(
199 g_browser_process->metrics_service()->GetInstallDate());
202 scoped_ptr<SigninClient::CookieChangedCallbackList::Subscription>
203 ChromeSigninClient::AddCookieChangedCallback(
204 const CookieChangedCallback& callback) {
205 scoped_ptr<SigninClient::CookieChangedCallbackList::Subscription>
206 subscription = callbacks_.Add(callback);
207 RegisterForCookieChangedNotification();
208 return subscription.Pass();
211 void ChromeSigninClient::GoogleSigninSucceeded(const std::string& account_id,
212 const std::string& username,
213 const std::string& password) {
214 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
215 // Don't store password hash except for users of new profile management.
216 if (switches::IsNewProfileManagement())
217 chrome::SetLocalAuthCredentials(profile_, password);
218 #endif
221 void ChromeSigninClient::Observe(int type,
222 const content::NotificationSource& source,
223 const content::NotificationDetails& details) {
224 switch (type) {
225 case chrome::NOTIFICATION_COOKIE_CHANGED: {
226 DCHECK(!callbacks_.empty());
227 const net::CanonicalCookie* cookie =
228 content::Details<ChromeCookieDetails>(details).ptr()->cookie;
229 callbacks_.Notify(cookie);
230 break;
232 default:
233 NOTREACHED();
234 break;
238 void ChromeSigninClient::RegisterForCookieChangedNotification() {
239 if (callbacks_.empty())
240 return;
241 content::Source<Profile> source(profile_);
242 if (!registrar_.IsRegistered(
243 this, chrome::NOTIFICATION_COOKIE_CHANGED, source))
244 registrar_.Add(this, chrome::NOTIFICATION_COOKIE_CHANGED, source);
247 void ChromeSigninClient::UnregisterForCookieChangedNotification() {
248 if (!callbacks_.empty())
249 return;
250 // Note that it's allowed to call this method multiple times without an
251 // intervening call to |RegisterForCookieChangedNotification()|.
252 content::Source<Profile> source(profile_);
253 if (!registrar_.IsRegistered(
254 this, chrome::NOTIFICATION_COOKIE_CHANGED, source))
255 return;
256 registrar_.Remove(this, chrome::NOTIFICATION_COOKIE_CHANGED, source);