blob: da78f9cb1f5f904b1e24cd0380c367a022b2d155 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/profile_internals/profile_internals_handler.h"
#include <optional>
#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/json/values_util.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/regional_capabilities/regional_capabilities_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/profiles/profile_colors_util.h"
#include "components/country_codes/country_codes.h"
#include "components/regional_capabilities/access/country_access_reason.h"
#include "components/regional_capabilities/regional_capabilities_country_id.h"
#include "components/regional_capabilities/regional_capabilities_service.h"
#include "components/search_engines/template_url_service.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/variations/service/variations_service.h"
#include "content/public/browser/web_ui.h"
#include "google_apis/gaia/gaia_id.h"
#include "skia/ext/skia_utils_base.h"
using regional_capabilities::CountryIdHolder;
// static
std::string ProfileInternalsHandler::CountryIdToDebugString(
std::optional<CountryIdHolder> country_id) {
if (!country_id.has_value()) {
return "not available";
}
if (country_id.value() == CountryIdHolder(country_codes::CountryId())) {
return "unknown";
}
return std::string(
country_id
->GetRestricted(regional_capabilities::CountryAccessKey(
regional_capabilities::CountryAccessReason::
kProfileInternalsDisplayInDebugUi))
.CountryCode());
}
// static
base::Value::Dict ProfileInternalsHandler::CreateProfileEntry(
const ProfileAttributesEntry* entry) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
Profile* loaded_profile = profile_manager->GetProfileByPath(entry->GetPath());
base::Value::Dict profile_entry;
profile_entry.Set("profilePath", base::FilePathToValue(entry->GetPath()));
profile_entry.Set("localProfileName", entry->GetLocalProfileName());
std::string signin_state;
switch (entry->GetSigninState()) {
case SigninState::kNotSignedIn:
signin_state = "Not signed in";
break;
case SigninState::kSignedInWithUnconsentedPrimaryAccount:
signin_state = "Signed in with unconsented primary account";
break;
case SigninState::kSignedInWithConsentedPrimaryAccount:
signin_state = "Signed in with consented primary account";
break;
}
profile_entry.Set("signinState", signin_state);
profile_entry.Set("signinRequired", entry->IsSigninRequired());
// GAIA full name/user name can be empty, if the profile is not signed in to
// chrome.
profile_entry.Set("gaiaName", entry->GetGAIAName());
profile_entry.Set("gaiaId", entry->GetGAIAId().ToString());
profile_entry.Set("userName", entry->GetUserName());
profile_entry.Set("hostedDomain", entry->GetHostedDomain());
profile_entry.Set("isManaged",
signin::TriboolToString(entry->GetIsManaged()));
profile_entry.Set("isSupervised", entry->IsSupervised());
profile_entry.Set("isOmitted", entry->IsOmitted());
profile_entry.Set("isEphemeral", entry->IsEphemeral());
profile_entry.Set("userAcceptedAccountManagement",
entry->UserAcceptedAccountManagement());
SkColor highlight_color =
entry->GetProfileThemeColors().profile_highlight_color;
profile_entry.Set("backgroundColor",
skia::SkColorToHexString(highlight_color));
profile_entry.Set(
"foregroundColor",
skia::SkColorToHexString(GetProfileForegroundTextColor(highlight_color)));
base::Value::List keep_alives;
std::map<ProfileKeepAliveOrigin, int> keep_alives_map =
profile_manager->GetKeepAlivesByPath(entry->GetPath());
for (const auto& pair : keep_alives_map) {
if (pair.second != 0) {
std::stringstream ss;
ss << pair.first;
base::Value::Dict keep_alive_pair;
keep_alive_pair.Set("origin", ss.str());
keep_alive_pair.Set("count", pair.second);
keep_alives.Append(std::move(keep_alive_pair));
}
}
profile_entry.Set("keepAlives", std::move(keep_alives));
base::Value::List signedAccounts;
for (const GaiaId& gaiaId : entry->GetGaiaIds()) {
signedAccounts.Append(gaiaId.ToString());
}
profile_entry.Set("signedAccounts", std::move(signedAccounts));
profile_entry.Set("isLoaded", loaded_profile != nullptr);
profile_entry.Set(
"hasOffTheRecord",
loaded_profile &&
loaded_profile->GetAllOffTheRecordProfiles().size() > 0);
std::optional<CountryIdHolder> profile_country;
std::optional<CountryIdHolder> initial_keywords_db_country;
std::optional<CountryIdHolder> updated_keywords_db_country;
if (loaded_profile) {
profile_country =
regional_capabilities::RegionalCapabilitiesServiceFactory::
GetForProfile(loaded_profile)
->GetCountryId();
auto* template_url_service =
TemplateURLServiceFactory::GetForProfile(loaded_profile);
initial_keywords_db_country =
template_url_service->initial_keywords_database_country();
updated_keywords_db_country =
template_url_service->updated_keywords_database_country();
}
profile_entry.Set("profileCountry", CountryIdToDebugString(profile_country));
profile_entry.Set("initialKeywordsDbCountry",
CountryIdToDebugString(initial_keywords_db_country));
profile_entry.Set("updatedKeywordsDbCountry",
CountryIdToDebugString(updated_keywords_db_country));
profile_entry.Set(
"variationsCountry",
g_browser_process->variations_service()
? g_browser_process->variations_service()->GetLatestCountry()
: "not available");
profile_entry.Set("localeCountry",
country_codes::GetCurrentCountryID().CountryCode());
return profile_entry;
}
ProfileInternalsHandler::ProfileInternalsHandler() = default;
ProfileInternalsHandler::~ProfileInternalsHandler() = default;
void ProfileInternalsHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"getProfilesList",
base::BindRepeating(&ProfileInternalsHandler::HandleGetProfilesList,
base::Unretained(this)));
}
void ProfileInternalsHandler::HandleGetProfilesList(
const base::Value::List& args) {
AllowJavascript();
CHECK_EQ(0u, args.size());
PushProfilesList();
}
void ProfileInternalsHandler::PushProfilesList() {
DCHECK(IsJavascriptAllowed());
FireWebUIListener("profiles-list-changed", GetProfilesList());
}
base::Value::List ProfileInternalsHandler::GetProfilesList() {
base::Value::List profiles_list;
std::vector<ProfileAttributesEntry*> entries =
g_browser_process->profile_manager()
->GetProfileAttributesStorage()
.GetAllProfilesAttributesSortedByLocalProfileNameWithCheck();
for (const ProfileAttributesEntry* entry : entries) {
profiles_list.Append(CreateProfileEntry(entry));
}
return profiles_list;
}