Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / ios / chrome / browser / signin / signin_client_impl.cc
blob56c8a960e15e217358a3bbcea5d845db024d3a16
1 // Copyright 2015 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 "ios/chrome/browser/signin/signin_client_impl.h"
7 #include "base/command_line.h"
8 #include "base/guid.h"
9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/content_settings/core/browser/cookie_settings.h"
13 #include "components/keyed_service/core/service_access_type.h"
14 #include "components/metrics/metrics_service.h"
15 #include "components/signin/core/browser/profile_oauth2_token_service.h"
16 #include "components/signin/core/browser/signin_cookie_changed_subscription.h"
17 #include "components/signin/core/browser/signin_header_helper.h"
18 #include "components/signin/ios/browser/profile_oauth2_token_service_ios_provider.h"
19 #include "google_apis/gaia/gaia_constants.h"
20 #include "google_apis/gaia/gaia_urls.h"
21 #include "ios/chrome/browser/application_context.h"
22 #include "ios/chrome/browser/content_settings/cookie_settings_factory.h"
23 #include "ios/chrome/browser/signin/gaia_auth_fetcher_ios.h"
24 #include "ios/chrome/browser/web_data_service_factory.h"
25 #include "ios/chrome/common/channel_info.h"
26 #include "ios/public/provider/chrome/browser/browser_state/browser_state_info_cache.h"
27 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
28 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h"
29 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
30 #include "net/url_request/url_request_context_getter.h"
31 #include "url/gurl.h"
33 SigninClientImpl::SigninClientImpl(
34 ios::ChromeBrowserState* browser_state,
35 SigninErrorController* signin_error_controller)
36 : OAuth2TokenService::Consumer("signin_client_impl"),
37 browser_state_(browser_state),
38 signin_error_controller_(signin_error_controller) {
39 signin_error_controller_->AddObserver(this);
40 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
43 SigninClientImpl::~SigninClientImpl() {
44 signin_error_controller_->RemoveObserver(this);
47 void SigninClientImpl::Shutdown() {
48 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
51 void SigninClientImpl::DoFinalInit() {
54 // static
55 bool SigninClientImpl::AllowsSigninCookies(
56 ios::ChromeBrowserState* browser_state) {
57 scoped_refptr<content_settings::CookieSettings> cookie_settings =
58 ios::CookieSettingsFactory::GetForBrowserState(browser_state);
59 return signin::SettingsAllowSigninCookies(cookie_settings.get());
62 PrefService* SigninClientImpl::GetPrefs() {
63 return browser_state_->GetPrefs();
66 scoped_refptr<TokenWebData> SigninClientImpl::GetDatabase() {
67 return ios::WebDataServiceFactory::GetTokenWebDataForBrowserState(
68 browser_state_, ServiceAccessType::EXPLICIT_ACCESS);
71 bool SigninClientImpl::CanRevokeCredentials() {
72 return true;
75 std::string SigninClientImpl::GetSigninScopedDeviceId() {
76 return GetOrCreateScopedDeviceIdPref(GetPrefs());
79 void SigninClientImpl::OnSignedOut() {
80 ios::BrowserStateInfoCache* cache = GetApplicationContext()
81 ->GetChromeBrowserStateManager()
82 ->GetBrowserStateInfoCache();
83 size_t index = cache->GetIndexOfBrowserStateWithPath(
84 browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
86 // If sign out occurs because Sync setup was in progress and the browser state
87 // got deleted, then it is no longer in the cache.
88 if (index == std::string::npos)
89 return;
91 cache->SetLocalAuthCredentialsOfBrowserStateAtIndex(index, std::string());
92 cache->SetAuthInfoOfBrowserStateAtIndex(index, std::string(),
93 base::string16());
94 cache->SetBrowserStateSigninRequiredAtIndex(index, false);
97 net::URLRequestContextGetter* SigninClientImpl::GetURLRequestContext() {
98 return browser_state_->GetRequestContext();
101 bool SigninClientImpl::ShouldMergeSigninCredentialsIntoCookieJar() {
102 return false;
105 std::string SigninClientImpl::GetProductVersion() {
106 return GetVersionString();
109 bool SigninClientImpl::IsFirstRun() const {
110 return false;
113 base::Time SigninClientImpl::GetInstallDate() {
114 return base::Time::FromTimeT(
115 GetApplicationContext()->GetMetricsService()->GetInstallDate());
118 bool SigninClientImpl::AreSigninCookiesAllowed() {
119 return AllowsSigninCookies(browser_state_);
122 void SigninClientImpl::AddContentSettingsObserver(
123 content_settings::Observer* observer) {
124 browser_state_->GetHostContentSettingsMap()->AddObserver(observer);
127 void SigninClientImpl::RemoveContentSettingsObserver(
128 content_settings::Observer* observer) {
129 browser_state_->GetHostContentSettingsMap()->RemoveObserver(observer);
132 scoped_ptr<SigninClient::CookieChangedSubscription>
133 SigninClientImpl::AddCookieChangedCallback(
134 const GURL& url,
135 const std::string& name,
136 const net::CookieStore::CookieChangedCallback& callback) {
137 scoped_refptr<net::URLRequestContextGetter> context_getter =
138 browser_state_->GetRequestContext();
139 DCHECK(context_getter.get());
140 scoped_ptr<SigninCookieChangedSubscription> subscription(
141 new SigninCookieChangedSubscription(context_getter, url, name, callback));
142 return subscription.Pass();
145 void SigninClientImpl::OnSignedIn(const std::string& account_id,
146 const std::string& gaia_id,
147 const std::string& username,
148 const std::string& password) {
149 ios::ChromeBrowserStateManager* browser_state_manager =
150 GetApplicationContext()->GetChromeBrowserStateManager();
151 ios::BrowserStateInfoCache* cache =
152 browser_state_manager->GetBrowserStateInfoCache();
153 size_t index = cache->GetIndexOfBrowserStateWithPath(
154 browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
155 if (index != std::string::npos) {
156 cache->SetAuthInfoOfBrowserStateAtIndex(index, gaia_id,
157 base::UTF8ToUTF16(username));
161 bool SigninClientImpl::UpdateAccountInfo(
162 AccountTrackerService::AccountInfo* out_account_info) {
163 DCHECK(!out_account_info->account_id.empty());
164 AccountInfo account_info = ios::GetChromeBrowserProvider()
165 ->GetProfileOAuth2TokenServiceIOSProvider()
166 ->GetAccountInfo(out_account_info->account_id);
167 if (account_info.gaia.empty()) {
168 // There is no account information for this account, so there is nothing
169 // to be updated here.
170 return false;
173 bool updated = false;
174 if (out_account_info->gaia.empty()) {
175 out_account_info->gaia = account_info.gaia;
176 updated = true;
177 } else if (out_account_info->gaia != account_info.gaia) {
178 // The GAIA id of an account never changes. Avoid updating the wrong
179 // account if this occurs somehow.
180 NOTREACHED() << "out_account_info->gaia = '" << out_account_info->gaia
181 << "' ; account_info.gaia = '" << account_info.gaia << "'";
182 return false;
184 if (out_account_info->email != account_info.email) {
185 out_account_info->email = account_info.email;
186 updated = true;
188 return updated;
191 void SigninClientImpl::OnErrorChanged() {
192 ios::BrowserStateInfoCache* cache = GetApplicationContext()
193 ->GetChromeBrowserStateManager()
194 ->GetBrowserStateInfoCache();
195 size_t index = cache->GetIndexOfBrowserStateWithPath(
196 browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
197 if (index == std::string::npos)
198 return;
200 cache->SetBrowserStateIsAuthErrorAtIndex(
201 index, signin_error_controller_->HasError());
204 void SigninClientImpl::OnGetTokenInfoResponse(
205 scoped_ptr<base::DictionaryValue> token_info) {
206 if (!token_info->HasKey("error")) {
207 std::string handle;
208 if (token_info->GetString("token_handle", &handle)) {
209 ios::BrowserStateInfoCache* cache = GetApplicationContext()
210 ->GetChromeBrowserStateManager()
211 ->GetBrowserStateInfoCache();
212 size_t index = cache->GetIndexOfBrowserStateWithPath(
213 browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
214 cache->SetPasswordChangeDetectionTokenAtIndex(index, handle);
215 } else {
216 NOTREACHED();
219 oauth_request_.reset();
222 void SigninClientImpl::OnOAuthError() {
223 // Ignore the failure. It's not essential and we'll try again next time.
224 oauth_request_.reset();
227 void SigninClientImpl::OnNetworkError(int response_code) {
228 // Ignore the failure. It's not essential and we'll try again next time.
229 oauth_request_.reset();
232 void SigninClientImpl::OnGetTokenSuccess(
233 const OAuth2TokenService::Request* request,
234 const std::string& access_token,
235 const base::Time& expiration_time) {
236 // Exchange the access token for a handle that can be used for later
237 // verification that the token is still valid (i.e. the password has not
238 // been changed).
239 if (!oauth_client_) {
240 oauth_client_.reset(
241 new gaia::GaiaOAuthClient(browser_state_->GetRequestContext()));
243 oauth_client_->GetTokenInfo(access_token, 3 /* retries */, this);
246 void SigninClientImpl::OnGetTokenFailure(
247 const OAuth2TokenService::Request* request,
248 const GoogleServiceAuthError& error) {
249 // Ignore the failure. It's not essential and we'll try again next time.
250 oauth_request_.reset();
253 void SigninClientImpl::OnNetworkChanged(
254 net::NetworkChangeNotifier::ConnectionType type) {
255 if (type >= net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE)
256 return;
258 for (const base::Closure& callback : delayed_callbacks_)
259 callback.Run();
261 delayed_callbacks_.clear();
264 void SigninClientImpl::DelayNetworkCall(const base::Closure& callback) {
265 // Don't bother if we don't have any kind of network connection.
266 if (net::NetworkChangeNotifier::IsOffline()) {
267 delayed_callbacks_.push_back(callback);
268 } else {
269 callback.Run();
273 GaiaAuthFetcher* SigninClientImpl::CreateGaiaAuthFetcher(
274 GaiaAuthConsumer* consumer,
275 const std::string& source,
276 net::URLRequestContextGetter* getter) {
277 return new GaiaAuthFetcherIOS(consumer, source, getter, browser_state_);