blob: 51c228e946bc9b1fed2ede70a86478c92cdddc65 [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/signin/signin_util.h"
#import "base/no_destructor.h"
#import "base/strings/sys_string_conversions.h"
#import "base/values.h"
#import "components/prefs/pref_service.h"
#import "components/prefs/scoped_user_pref_update.h"
#import "components/signin/public/identity_manager/tribool.h"
#import "google_apis/gaia/core_account_id.h"
#import "google_apis/gaia/gaia_auth_util.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/signin/signin_util_internal.h"
#import "ios/chrome/browser/signin/system_identity.h"
#import "ios/public/provider/chrome/browser/signin/signin_error_api.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
absl::optional<AccountInfo>& GetPreRestoreIdentity() {
static base::NoDestructor<absl::optional<AccountInfo>> pre_restore_identity;
return *pre_restore_identity;
}
const char kAccountInfoKeyAccountId[] = "account_id";
const char kAccountInfoKeyGaia[] = "gaia";
const char kAccountInfoKeyEmail[] = "email";
const char kAccountInfoKeyFullName[] = "full_name";
const char kAccountInfoKeyGivenName[] = "given_name";
const char kAccountInfoKeyPictureUrl[] = "picture_url";
// Copies a string value from a dictionary if the given key is present.
void CopyStringFromDict(std::string& to,
const base::Value::Dict& dict,
const char* key) {
const std::string* found = dict.FindString(key);
if (found) {
to = *found;
}
}
// Returns an AccountInfo from the values in a dictionary.
AccountInfo DictToAccountInfo(const base::Value::Dict& dict) {
AccountInfo account;
const std::string* account_id_str = dict.FindString(kAccountInfoKeyAccountId);
if (account_id_str) {
account.account_id = CoreAccountId::FromString(*account_id_str);
}
CopyStringFromDict(account.gaia, dict, kAccountInfoKeyGaia);
CopyStringFromDict(account.email, dict, kAccountInfoKeyEmail);
CopyStringFromDict(account.full_name, dict, kAccountInfoKeyFullName);
CopyStringFromDict(account.given_name, dict, kAccountInfoKeyGivenName);
CopyStringFromDict(account.picture_url, dict, kAccountInfoKeyPictureUrl);
return account;
}
} // namespace
NSArray* GetScopeArray(const std::set<std::string>& scopes) {
NSMutableArray* scopes_array = [[NSMutableArray alloc] init];
for (const auto& scope : scopes) {
[scopes_array addObject:base::SysUTF8ToNSString(scope)];
}
return scopes_array;
}
bool ShouldHandleSigninError(NSError* error) {
return ios::provider::GetSigninErrorCategory(error) !=
ios::provider::SigninErrorCategory::kUserCancellationError;
}
CGSize GetSizeForIdentityAvatarSize(IdentityAvatarSize avatar_size) {
CGFloat size = 0;
switch (avatar_size) {
case IdentityAvatarSize::TableViewIcon:
size = 30.;
break;
case IdentityAvatarSize::SmallSize:
size = 32.;
break;
case IdentityAvatarSize::Regular:
size = 40.;
break;
case IdentityAvatarSize::Large:
size = 48.;
break;
case IdentityAvatarSize::ExtraLarge:
size = 60.;
break;
}
DCHECK_NE(size, 0);
return CGSizeMake(size, size);
}
signin::Tribool IsFirstSessionAfterDeviceRestore() {
static signin::Tribool is_first_session_after_device_restore =
signin::Tribool::kUnknown;
static dispatch_once_t once;
dispatch_once(&once, ^{
is_first_session_after_device_restore =
IsFirstSessionAfterDeviceRestoreInternal();
});
return is_first_session_after_device_restore;
}
void StorePreRestoreIdentity(PrefService* local_state, AccountInfo account) {
absl::optional<AccountInfo>& pre_restore_identity = GetPreRestoreIdentity();
pre_restore_identity = account;
ScopedDictPrefUpdate update(local_state, prefs::kIosPreRestoreAccountInfo);
update->Set(kAccountInfoKeyAccountId, account.account_id.ToString());
update->Set(kAccountInfoKeyGaia, account.gaia);
update->Set(kAccountInfoKeyEmail, account.email);
update->Set(kAccountInfoKeyFullName, account.full_name);
update->Set(kAccountInfoKeyGivenName, account.given_name);
update->Set(kAccountInfoKeyPictureUrl, account.picture_url);
}
void ClearPreRestoreIdentity(PrefService* local_state) {
absl::optional<AccountInfo>& pre_restore_identity = GetPreRestoreIdentity();
pre_restore_identity.reset();
local_state->ClearPref(prefs::kIosPreRestoreAccountInfo);
}
absl::optional<AccountInfo> GetPreRestoreIdentity(PrefService* local_state) {
absl::optional<AccountInfo>& pre_restore_identity = GetPreRestoreIdentity();
if (!pre_restore_identity.has_value()) {
const base::Value::Dict& dict =
local_state->GetDict(prefs::kIosPreRestoreAccountInfo);
if (!dict.empty()) {
pre_restore_identity = DictToAccountInfo(dict);
}
}
return pre_restore_identity;
}