blob: f5cf8e62b1d80c1fe559c31c96ccb4132a42b452 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/browser/shared/model/profile/profile_attributes_ios.h"
#include "base/check.h"
#include "base/json/values_util.h"
#include "base/strings/string_util.h"
#include "google_apis/gaia/gaia_id.h"
namespace {
using Dict = base::Value::Dict;
// Constants used as key in the dictionary.
constexpr std::string_view kActiveTimeKey = "active_time";
constexpr std::string_view kGaiaIdKey = "gaia_id";
constexpr std::string_view kIsAuthErrorKey = "is_auth_error";
constexpr std::string_view kAttachedGaiaIdsKey = "attached_gaia_ids";
constexpr std::string_view kUserNameKey = "user_name";
constexpr std::string_view kNewProfile = "new_profile";
constexpr std::string_view kIsFullyInitializedKey = "fully_initialized";
constexpr std::string_view kIsDeletedProfile = "deleted_profile";
constexpr std::string_view kDiscardedSessions = "discarded_sessions";
constexpr std::string_view kNotificationPermissions =
"notification_permissions";
// Converts `value` to a base::Value.
base::Value ToValue(const std::string& value) {
return base::Value(value);
}
// Converts `value` to a base::Value.
base::Value ToValue(const GaiaId& value) {
return base::Value(value.ToString());
}
// Retrieves a bool value from the dictionary.
bool GetBool(const Dict& dict, std::string_view key) {
return dict.FindBool(key).value_or(false);
}
// Stores a bool value in the dictionary.
void SetBool(Dict& dict, std::string_view key, bool value) {
if (!value) {
dict.Remove(key);
} else {
dict.Set(key, value);
}
}
// Retrieves a Time value from the dictionary.
base::Time GetTime(const Dict& dict, std::string_view key) {
return base::ValueToTime(dict.Find(key)).value_or(base::Time());
}
// Stores a Time value in the dictionary.
void SetTime(Dict& dict, std::string_view key, base::Time value) {
if (value == base::Time()) {
dict.Remove(key);
} else {
dict.Set(key, base::TimeToValue(value));
}
}
// Retrieves a string value from the dictionary.
const std::string& GetString(const Dict& dict, std::string_view key) {
const std::string* string = dict.FindString(key);
return string ? *string : base::EmptyString();
}
// Stores a string value in the dictionary.
void SetString(Dict& dict, std::string_view key, std::string_view value) {
if (value.empty()) {
dict.Remove(key);
} else {
dict.Set(key, value);
}
}
// Retrieves a string set value from the dictionary.
template <typename StringSet = std::set<std::string>>
StringSet GetStringSet(const Dict& dict, std::string_view key) {
StringSet set;
if (const base::Value::List* list = dict.FindList(key)) {
for (const base::Value& value : *list) {
if (const std::string* string = value.GetIfString()) {
set.emplace(*string);
}
}
}
return set;
}
// Stores a string set value in the dictionary.
template <typename StringSet = std::set<std::string>>
void SetStringSet(Dict& dict, std::string_view key, const StringSet& set) {
if (set.empty()) {
dict.Remove(key);
} else {
base::Value::List list;
for (const auto& string : set) {
list.Append(ToValue(string));
}
dict.Set(key, std::move(list));
}
}
// Retrieves a dictionary value from the storage dictionary.
const Dict* GetDict(const Dict& dict, std::string_view key) {
return dict.FindDict(key);
}
// Sets a dictionary value in the storage dictionary.
void SetDict(Dict& dict, std::string_view key, Dict value) {
if (value.empty()) {
dict.Remove(key);
} else {
dict.Set(key, std::move(value));
}
}
} // namespace
// static
ProfileAttributesIOS ProfileAttributesIOS::CreateNew(
std::string_view profile_name) {
base::Value::Dict dict;
SetBool(dict, kNewProfile, true);
return ProfileAttributesIOS(profile_name, std::move(dict));
}
// static
ProfileAttributesIOS ProfileAttributesIOS::WithAttrs(
std::string_view profile_name,
const base::Value::Dict& storage) {
return ProfileAttributesIOS(profile_name, storage.Clone());
}
ProfileAttributesIOS ProfileAttributesIOS::DeletedProfile(
std::string_view profile_name) {
base::Value::Dict dict;
SetBool(dict, kIsDeletedProfile, true);
return ProfileAttributesIOS(profile_name, std::move(dict));
}
ProfileAttributesIOS::ProfileAttributesIOS(ProfileAttributesIOS&&) = default;
ProfileAttributesIOS& ProfileAttributesIOS::operator=(ProfileAttributesIOS&&) =
default;
ProfileAttributesIOS::~ProfileAttributesIOS() = default;
const std::string& ProfileAttributesIOS::ProfileAttributesIOS::GetProfileName()
const {
return profile_name_;
}
bool ProfileAttributesIOS::IsNewProfile() const {
return GetBool(storage_, kNewProfile);
}
bool ProfileAttributesIOS::IsFullyInitialized() const {
return GetBool(storage_, kIsFullyInitializedKey);
}
bool ProfileAttributesIOS::IsDeletedProfile() const {
return GetBool(storage_, kIsDeletedProfile);
}
GaiaId ProfileAttributesIOS::GetGaiaId() const {
return GaiaId(GetString(storage_, kGaiaIdKey));
}
const std::string& ProfileAttributesIOS::GetUserName() const {
return GetString(storage_, kUserNameKey);
}
bool ProfileAttributesIOS::HasAuthenticationError() const {
return GetBool(storage_, kIsAuthErrorKey);
}
ProfileAttributesIOS::GaiaIdSet ProfileAttributesIOS::GetAttachedGaiaIds()
const {
return GetStringSet<GaiaIdSet>(storage_, kAttachedGaiaIdsKey);
}
base::Time ProfileAttributesIOS::GetLastActiveTime() const {
return GetTime(storage_, kActiveTimeKey);
}
bool ProfileAttributesIOS::IsAuthenticated() const {
// The profile is authenticated if the gaia_id is not empty. If it is empty,
// check if the username is not empty. This latter check is needed in case
// the profile has not been loaded and the gaia_id has not been written yet.
return !GetGaiaId().empty() || !GetUserName().empty();
}
ProfileAttributesIOS::SessionIds ProfileAttributesIOS::GetDiscardedSessions()
const {
return GetStringSet<SessionIds>(storage_, kDiscardedSessions);
}
const Dict* ProfileAttributesIOS::GetNotificationPermissions() const {
return GetDict(storage_, kNotificationPermissions);
}
void ProfileAttributesIOS::ClearIsNewProfile() {
SetBool(storage_, kNewProfile, false);
}
void ProfileAttributesIOS::SetFullyInitialized() {
SetBool(storage_, kIsFullyInitializedKey, true);
}
void ProfileAttributesIOS::SetAuthenticationInfo(const GaiaId& gaia_id,
std::string_view user_name) {
SetString(storage_, kGaiaIdKey, gaia_id.ToString());
SetString(storage_, kUserNameKey, user_name);
}
void ProfileAttributesIOS::SetHasAuthenticationError(bool value) {
SetBool(storage_, kIsAuthErrorKey, value);
}
void ProfileAttributesIOS::SetAttachedGaiaIds(const GaiaIdSet& gaia_ids) {
SetStringSet(storage_, kAttachedGaiaIdsKey, gaia_ids);
}
void ProfileAttributesIOS::SetLastActiveTime(base::Time time) {
SetTime(storage_, kActiveTimeKey, time);
}
void ProfileAttributesIOS::SetDiscardedSessions(const SessionIds& session_ids) {
SetStringSet(storage_, kDiscardedSessions, session_ids);
}
void ProfileAttributesIOS::SetNotificationPermissions(Dict permissions) {
SetDict(storage_, kNotificationPermissions, std::move(permissions));
}
base::Value::Dict ProfileAttributesIOS::GetStorage() && {
return std::move(storage_);
}
ProfileAttributesIOS::ProfileAttributesIOS(std::string_view profile_name,
base::Value::Dict storage)
: profile_name_(profile_name), storage_(std::move(storage)) {
DCHECK(!profile_name_.empty());
}