blob: 886e388cd6d4dc1ad75ea9c69aa24f34f87bea9f [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/profiles/profile_impl.h"
#include <stddef.h>
#include <memory>
#include <set>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/environment.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/trace_event/trace_event.h"
#include "base/version.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/ash/account_manager/account_manager_util.h"
#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/background_fetch/background_fetch_delegate_factory.h"
#include "chrome/browser/background_fetch/background_fetch_delegate_impl.h"
#include "chrome/browser/background_sync/background_sync_controller_factory.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.h"
#include "chrome/browser/client_hints/client_hints_factory.h"
#include "chrome/browser/content_index/content_index_provider_factory.h"
#include "chrome/browser/content_index/content_index_provider_impl.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
#include "chrome/browser/dom_distiller/profile_utils.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_manager_utils.h"
#include "chrome/browser/federated_learning/floc_id_provider.h"
#include "chrome/browser/federated_learning/floc_id_provider_factory.h"
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h"
#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h"
#include "chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h"
#include "chrome/browser/media/media_device_id_salt.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_builder.h"
#include "chrome/browser/policy/schema_registry_service.h"
#include "chrome/browser/policy/schema_registry_service_builder.h"
#include "chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include "chrome/browser/prefs/pref_service_syncable_util.h"
#include "chrome/browser/prefs/profile_pref_store_manager.h"
#include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
#include "chrome/browser/profiles/chrome_version_service.h"
#include "chrome/browser/profiles/gaia_info_update_service_factory.h"
#include "chrome/browser/profiles/pref_service_builder_utils.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_destroyer.h"
#include "chrome/browser/profiles/profile_key.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/push_messaging/push_messaging_service_factory.h"
#include "chrome/browser/push_messaging/push_messaging_service_impl.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/sharing/sharing_service_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_ui_util.h"
#include "chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.h"
#include "chrome/browser/startup_data.h"
#include "chrome/browser/storage/storage_notification_service_factory.h"
#include "chrome/browser/transition_manager/full_browser_transition_manager.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/browser/ui/webui/prefs_internals_source.h"
#include "chrome/browser/updates/announcement_notification/announcement_notification_service.h"
#include "chrome/browser/updates/announcement_notification/announcement_notification_service_factory.h"
#include "chrome/browser/webid/federated_identity_request_permission_context.h"
#include "chrome/browser/webid/federated_identity_request_permission_context_factory.h"
#include "chrome/browser/webid/federated_identity_sharing_permission_context.h"
#include "chrome/browser/webid/federated_identity_sharing_permission_context_factory.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/safe_search_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
#include "components/background_sync/background_sync_controller_impl.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/core/browser/data_store_impl.h"
#include "components/heavy_ad_intervention/heavy_ad_service.h"
#include "components/history/core/common/pref_names.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/core/simple_dependency_manager.h"
#include "components/keyed_service/core/simple_key_map.h"
#include "components/keyed_service/core/simple_keyed_service_factory.h"
#include "components/language/core/browser/pref_names.h"
#include "components/language/core/common/locale_util.h"
#include "components/metrics/metrics_service.h"
#include "components/omnibox/browser/autocomplete_classifier.h"
#include "components/permissions/permission_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_manager.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/profile_metrics/browser_profile_type.h"
#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/site_isolation/site_isolation_policy.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/url_formatter/url_fixer.h"
#include "components/user_prefs/user_prefs.h"
#include "components/version_info/channel.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/dom_storage_context.h"
#include "content/public/browser/federated_identity_request_permission_context_delegate.h"
#include "content/public/browser/federated_identity_sharing_permission_context_delegate.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/common/content_constants.h"
#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/preferences/public/mojom/preferences.mojom.h"
#include "services/preferences/public/mojom/tracked_preference_validation_delegate.mojom.h"
#include "services/service_manager/public/cpp/service.h"
#include "ui/base/l10n/l10n_util.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/components/account_manager/account_manager_factory.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/ash/app_mode/app_launch_utils.h"
#include "chrome/browser/ash/arc/session/arc_service_launcher.h"
#include "chrome/browser/ash/login/session/user_session_manager.h"
#include "chrome/browser/ash/policy/active_directory/active_directory_policy_manager.h"
#include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h"
#include "chrome/browser/ash/policy/core/user_policy_manager_builder_ash.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/settings/device_settings_service.h"
#include "chrome/browser/chromeos/locale_change_guard.h"
#include "chrome/browser/chromeos/preferences.h"
#include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h"
#include "chrome/browser/signin/chrome_device_id_helper.h"
#include "components/account_manager_core/chromeos/account_manager.h"
#include "components/session_manager/core/session_manager.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#else
#include "chrome/browser/policy/cloud/user_cloud_policy_manager_builder.h"
#endif
#if defined(OS_ANDROID)
#include "chrome/browser/android/profile_key_startup_accessor.h"
#else
#include "chrome/browser/first_run/first_run.h"
#include "components/zoom/zoom_event_manager.h"
#include "content/public/common/page_zoom.h"
#endif
#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
#include "chrome/browser/background/background_mode_manager.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "components/guest_view/browser/guest_view_manager.h"
#include "extensions/browser/extension_pref_store.h"
#include "extensions/browser/extension_pref_value_map.h"
#include "extensions/browser/extension_pref_value_map_factory.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_system.h"
#endif
#if BUILDFLAG(ENABLE_PLUGINS)
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#endif
#if BUILDFLAG(ENABLE_SESSION_SERVICE)
#include "chrome/browser/sessions/session_service_factory.h"
#endif
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/content_settings/content_settings_supervised_provider.h"
#include "chrome/browser/supervised_user/supervised_user_constants.h"
#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/browser_process.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 "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#include "components/policy/core/common/async_policy_provider.h"
#include "components/policy/core/common/policy_loader_lacros.h"
#include "components/policy/core/common/policy_proto_decoders.h"
#include "components/signin/public/base/signin_switches.h"
#endif
#if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
#include "chrome/browser/spellchecker/spellcheck_service.h"
#endif
using base::TimeDelta;
using bookmarks::BookmarkModel;
using content::BrowserThread;
using content::DownloadManagerDelegate;
namespace {
#if BUILDFLAG(ENABLE_SESSION_SERVICE)
// Delay before we explicitly create the SessionService.
static constexpr TimeDelta kCreateSessionServiceDelay =
TimeDelta::FromMilliseconds(500);
#endif
// Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED.
const char kPrefExitTypeCrashed[] = "Crashed";
const char kPrefExitTypeSessionEnded[] = "SessionEnded";
// Gets the creation time for |path|, returning base::Time::Now() on failure.
base::Time GetCreationTimeForPath(const base::FilePath& path) {
base::File::Info info;
if (base::GetFileInfo(path, &info))
return info.creation_time;
return base::Time::Now();
}
// Creates the profile directory synchronously if it doesn't exist. If
// |create_readme| is true, the profile README will be created asynchronously in
// the profile directory. Returns the creation time/date of the profile
// directory.
base::Time CreateProfileDirectory(base::SequencedTaskRunner* io_task_runner,
const base::FilePath& path,
bool create_readme) {
// Create the profile directory synchronously otherwise we would need to
// sequence every otherwise independent I/O operation inside the profile
// directory with this operation. base::PathExists() and
// base::CreateDirectory() should be lightweight I/O operations and avoiding
// the headache of sequencing all otherwise unrelated I/O after these
// justifies running them on the main thread.
base::ThreadRestrictions::ScopedAllowIO allow_io_to_create_directory;
// If the readme exists, the profile directory must also already exist.
if (base::PathExists(path.Append(chrome::kReadmeFilename)))
return GetCreationTimeForPath(path);
DVLOG(1) << "Creating directory " << path.value();
if (base::CreateDirectory(path)) {
if (create_readme) {
base::ThreadPool::PostTask(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
base::BindOnce(&CreateProfileReadme, path));
}
return GetCreationTimeForPath(path);
}
return base::Time::Now();
}
// Converts the `kSessionExitType` pref to the corresponding EXIT_TYPE.
Profile::ExitType SessionTypePrefValueToExitType(const std::string& value) {
if (value == kPrefExitTypeSessionEnded)
return Profile::EXIT_SESSION_ENDED;
if (value == kPrefExitTypeCrashed)
return Profile::EXIT_CRASHED;
return Profile::EXIT_NORMAL;
}
// Converts an ExitType into a string that is written to prefs.
std::string ExitTypeToSessionTypePrefValue(Profile::ExitType type) {
switch (type) {
case Profile::EXIT_NORMAL:
return ProfileImpl::kPrefExitTypeNormal;
case Profile::EXIT_SESSION_ENDED:
return kPrefExitTypeSessionEnded;
case Profile::EXIT_CRASHED:
return kPrefExitTypeCrashed;
}
NOTREACHED();
return std::string();
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Checks if |new_locale| is the same as |pref_locale| or |pref_locale| is used
// to show UI translation for |new_locale|. (e.g. "it" is used for "it-CH")
bool LocaleNotChanged(const std::string& pref_locale,
const std::string& new_locale) {
std::string new_locale_converted = new_locale;
language::ConvertToActualUILocale(&new_locale_converted);
return pref_locale == new_locale_converted;
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
} // namespace
// static
std::unique_ptr<Profile> Profile::CreateProfile(const base::FilePath& path,
Delegate* delegate,
CreateMode create_mode) {
TRACE_EVENT1("browser,startup", "Profile::CreateProfile", "profile_path",
path.AsUTF8Unsafe());
// Get sequenced task runner for making sure that file operations of
// this profile are executed in expected order (what was previously assured by
// the FILE thread).
scoped_refptr<base::SequencedTaskRunner> io_task_runner =
base::ThreadPool::CreateSequencedTaskRunner(
{base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
base::Time creation_time = base::Time::Now();
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
DCHECK(delegate);
creation_time = CreateProfileDirectory(io_task_runner.get(), path, true);
} else if (create_mode == CREATE_MODE_SYNCHRONOUS) {
if (base::PathExists(path)) {
creation_time = GetCreationTimeForPath(path);
} else {
// TODO(rogerta): http://crbug/160553 - Bad things happen if we can't
// write to the profile directory. We should eventually be able to run in
// this situation.
if (!base::CreateDirectory(path))
return nullptr;
CreateProfileReadme(path);
}
} else {
NOTREACHED();
}
std::unique_ptr<Profile> profile = base::WrapUnique(new ProfileImpl(
path, delegate, create_mode, creation_time, io_task_runner));
return profile;
}
// static
const char ProfileImpl::kPrefExitTypeNormal[] = "Normal";
// static
void ProfileImpl::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled, false);
registry->RegisterBooleanPref(prefs::kAllowDeletingBrowserHistory, true);
registry->RegisterBooleanPref(prefs::kForceGoogleSafeSearch, false);
registry->RegisterIntegerPref(prefs::kForceYouTubeRestrict,
safe_search_util::YOUTUBE_RESTRICT_OFF);
registry->RegisterStringPref(prefs::kAllowedDomainsForApps, std::string());
registry->RegisterIntegerPref(prefs::kProfileAvatarIndex, -1);
// Whether a profile is using an avatar without having explicitely chosen it
// (i.e. was assigned by default by legacy profile creation).
registry->RegisterBooleanPref(prefs::kProfileUsingDefaultAvatar, true);
registry->RegisterBooleanPref(prefs::kProfileUsingGAIAAvatar, false);
// Whether a profile is using a default avatar name (eg. Pickles or Person 1).
registry->RegisterBooleanPref(prefs::kProfileUsingDefaultName, true);
registry->RegisterStringPref(prefs::kProfileName, std::string());
registry->RegisterStringPref(prefs::kSupervisedUserId, std::string());
#if defined(OS_ANDROID)
uint32_t home_page_flags = PrefRegistry::NO_REGISTRATION_FLAGS;
#else
uint32_t home_page_flags = user_prefs::PrefRegistrySyncable::SYNCABLE_PREF;
#endif
registry->RegisterStringPref(prefs::kHomePage, std::string(),
home_page_flags);
registry->RegisterStringPref(prefs::kNewTabPageLocationOverride,
std::string());
#if BUILDFLAG(ENABLE_PRINTING)
registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
#endif // BUILDFLAG(ENABLE_PRINTING)
registry->RegisterBooleanPref(prefs::kPrintPreviewDisabled, false);
registry->RegisterStringPref(
prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string());
#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
registry->RegisterIntegerPref(prefs::kPrintRasterizationMode, 0);
#endif
registry->RegisterBooleanPref(prefs::kForceEphemeralProfiles, false);
registry->RegisterBooleanPref(prefs::kEnableMediaRouter, true);
#if !defined(OS_ANDROID)
registry->RegisterBooleanPref(prefs::kShowCastIconInToolbar, false);
#endif // !defined(OS_ANDROID)
registry->RegisterTimePref(prefs::kProfileCreationTime, base::Time());
#if BUILDFLAG(IS_CHROMEOS_ASH)
registry->RegisterBooleanPref(prefs::kPdfAnnotationsEnabled, true);
#endif
}
ProfileImpl::ProfileImpl(
const base::FilePath& path,
Delegate* delegate,
CreateMode create_mode,
base::Time path_creation_time,
scoped_refptr<base::SequencedTaskRunner> io_task_runner)
: path_(path),
path_creation_time_(path_creation_time),
io_task_runner_(std::move(io_task_runner)),
last_session_exit_type_(EXIT_NORMAL),
start_time_(base::Time::Now()),
delegate_(delegate) {
TRACE_EVENT0("browser,startup", "ProfileImpl::ctor");
DCHECK(!path.empty()) << "Using an empty path will attempt to write "
<< "profile files to the root directory!";
#if BUILDFLAG(IS_CHROMEOS_ASH)
const bool is_regular_profile =
chromeos::ProfileHelper::IsRegularProfile(this);
if (is_regular_profile) {
const user_manager::User* user =
chromeos::ProfileHelper::Get()->GetUserByProfile(this);
// A |User| instance should always exist for a profile which is not the
// initial, the sign-in or the lock screen app profile.
CHECK(user);
LOG_IF(FATAL,
!session_manager::SessionManager::Get()->HasSessionForAccountId(
user->GetAccountId()))
<< "Attempting to construct the profile before starting the user "
"session";
}
#endif
#if BUILDFLAG(ENABLE_SESSION_SERVICE)
create_session_service_timer_.Start(
FROM_HERE, kCreateSessionServiceDelay, this,
&ProfileImpl::EnsureSessionServiceCreated);
#endif
if (path == ProfileManager::GetGuestProfilePath()) {
profile_metrics::SetBrowserProfileType(
this, profile_metrics::BrowserProfileType::kGuest);
} else if (path == ProfileManager::GetSystemProfilePath()) {
profile_metrics::SetBrowserProfileType(
this, profile_metrics::BrowserProfileType::kSystem);
} else {
profile_metrics::SetBrowserProfileType(
this, profile_metrics::BrowserProfileType::kRegular);
}
// The ProfileImpl can be created both synchronously and asynchronously.
bool async_prefs = create_mode == CREATE_MODE_ASYNCHRONOUS;
#if defined(OS_ANDROID)
auto* startup_data = g_browser_process->startup_data();
DCHECK(startup_data && startup_data->GetProfileKey());
TakePrefsFromStartupData();
async_prefs = false;
#else
LoadPrefsForNormalStartup(async_prefs);
#endif
// Register on BrowserContext.
user_prefs::UserPrefs::Set(this, prefs_.get());
#if defined(OS_ANDROID)
// On Android StartupData creates proto database provider for the profile
// before profile is created, so move ownership to storage partition.
GetDefaultStoragePartition()->SetProtoDatabaseProvider(
startup_data->TakeProtoDatabaseProvider());
#endif
SimpleKeyMap::GetInstance()->Associate(this, key_.get());
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (is_regular_profile) {
// |ash::InitializeAccountManager| is called during a User's session
// initialization but some tests do not properly login to a User Session.
// This invocation of |ash::InitializeAccountManager| is used only during
// tests.
// Note: |ash::InitializeAccountManager| is idempotent and safe to call
// multiple times.
// TODO(https://crbug.com/982233): Remove this call.
ash::InitializeAccountManager(
path_, base::DoNothing() /* initialization_callback */);
auto* account_manager = g_browser_process->platform_part()
->GetAccountManagerFactory()
->GetAccountManager(path_.value());
account_manager->SetPrefService(GetPrefs());
}
#endif
if (delegate_)
delegate_->OnProfileCreationStarted(this, create_mode);
if (async_prefs) {
// Wait for the notification that prefs has been loaded
// (successfully or not). Note that we can use base::Unretained
// because the PrefService is owned by this class and lives on
// the same thread.
prefs_->AddPrefInitObserver(base::BindOnce(
&ProfileImpl::OnPrefsLoaded, base::Unretained(this), create_mode));
} else {
// Prefs were loaded synchronously so we can continue directly.
OnPrefsLoaded(create_mode, true);
}
#if !defined(OS_ANDROID)
if (IsGuestSession()) {
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
base::UmaHistogramBoolean(
"Profile.Guest.ForcedByPolicy",
local_state->GetBoolean(prefs::kBrowserGuestModeEnforced));
}
#endif // !defined(OS_ANDROID)
}
#if defined(OS_ANDROID)
void ProfileImpl::TakePrefsFromStartupData() {
auto* startup_data = g_browser_process->startup_data();
// On Android, it is possible that the ProfileKey has been build before the
// ProfileImpl is created. The ownership of all these pre-created objects
// will be taken by ProfileImpl.
key_ = startup_data->TakeProfileKey();
prefs_ = startup_data->TakeProfilePrefService();
schema_registry_service_ = startup_data->TakeSchemaRegistryService();
user_cloud_policy_manager_ = startup_data->TakeUserCloudPolicyManager();
profile_policy_connector_ = startup_data->TakeProfilePolicyConnector();
pref_registry_ = startup_data->TakePrefRegistrySyncable();
ProfileKeyStartupAccessor::GetInstance()->Reset();
}
#endif
void ProfileImpl::LoadPrefsForNormalStartup(bool async_prefs) {
key_ = std::make_unique<ProfileKey>(GetPath());
pref_registry_ = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
policy::ChromeBrowserPolicyConnector* connector =
g_browser_process->browser_policy_connector();
schema_registry_service_ = BuildSchemaRegistryServiceForProfile(
this, connector->GetChromeSchema(), connector->GetSchemaRegistry());
// If we are creating the profile synchronously, then we should load the
// policy data immediately.
bool force_immediate_policy_load = !async_prefs;
policy::UserCloudPolicyManager* user_cloud_policy_manager;
policy::ConfigurationPolicyProvider* policy_provider;
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (force_immediate_policy_load)
ash::DeviceSettingsService::Get()->LoadImmediately();
policy::CreateConfigurationPolicyProvider(
this, force_immediate_policy_load, io_task_runner_,
&user_cloud_policy_manager_ash_, &active_directory_policy_manager_);
user_cloud_policy_manager = nullptr;
policy_provider = GetUserCloudPolicyManagerAsh();
if (!policy_provider) {
policy_provider = GetActiveDirectoryPolicyManager();
}
#else // !BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_CHROMEOS_LACROS)
if (IsMainProfile()) {
auto loader = std::make_unique<policy::PolicyLoaderLacros>(
io_task_runner_, policy::PolicyPerProfileFilter::kTrue);
user_policy_provider_ = std::make_unique<policy::AsyncPolicyProvider>(
schema_registry_service_->registry(), std::move(loader));
user_policy_provider_->Init(schema_registry_service_->registry());
policy_provider = user_policy_provider_.get();
user_cloud_policy_manager = nullptr;
} else
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
{
user_cloud_policy_manager_ = CreateUserCloudPolicyManager(
GetPath(), GetPolicySchemaRegistryService()->registry(),
force_immediate_policy_load, io_task_runner_);
user_cloud_policy_manager = user_cloud_policy_manager_.get();
policy_provider = user_cloud_policy_manager;
}
#endif
profile_policy_connector_ =
policy::CreateProfilePolicyConnectorForBrowserContext(
schema_registry_service_->registry(), user_cloud_policy_manager,
policy_provider, g_browser_process->browser_policy_connector(),
force_immediate_policy_load, this);
bool is_signin_profile = false;
#if BUILDFLAG(IS_CHROMEOS_ASH)
is_signin_profile = chromeos::ProfileHelper::IsSigninProfile(this);
#endif
::RegisterProfilePrefs(is_signin_profile,
g_browser_process->GetApplicationLocale(),
pref_registry_.get());
mojo::PendingRemote<prefs::mojom::TrackedPreferenceValidationDelegate>
pref_validation_delegate;
scoped_refptr<safe_browsing::SafeBrowsingService> safe_browsing_service(
g_browser_process->safe_browsing_service());
if (safe_browsing_service.get()) {
auto pref_validation_delegate_impl =
safe_browsing_service->CreatePreferenceValidationDelegate(this);
if (pref_validation_delegate_impl) {
mojo::MakeSelfOwnedReceiver(
std::move(pref_validation_delegate_impl),
pref_validation_delegate.InitWithNewPipeAndPassReceiver());
}
}
prefs_ =
CreatePrefService(pref_registry_, CreateExtensionPrefStore(this, false),
profile_policy_connector_->policy_service(),
g_browser_process->browser_policy_connector(),
std::move(pref_validation_delegate), GetIOTaskRunner(),
key_.get(), path_, async_prefs);
key_->SetPrefs(prefs_.get());
}
void ProfileImpl::DoFinalInit(CreateMode create_mode) {
TRACE_EVENT0("browser", "ProfileImpl::DoFinalInit");
PrefService* prefs = GetPrefs();
// Do not override the existing pref in case a profile directory is copied, or
// if the file system does not support creation time and the property (i.e.
// st_ctim in posix which is actually the last status change time when the
// inode was last updated) use to mimic it changes because of some other
// modification.
if (!prefs->HasPrefPath(prefs::kProfileCreationTime))
prefs->SetTime(prefs::kProfileCreationTime, path_creation_time_);
pref_change_registrar_.Init(prefs);
pref_change_registrar_.Add(
prefs::kSupervisedUserId,
base::BindRepeating(&ProfileImpl::UpdateSupervisedUserIdInStorage,
base::Unretained(this)));
// Changes in the profile avatar.
pref_change_registrar_.Add(
prefs::kProfileAvatarIndex,
base::BindRepeating(&ProfileImpl::UpdateAvatarInStorage,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kProfileUsingDefaultAvatar,
base::BindRepeating(&ProfileImpl::UpdateAvatarInStorage,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kProfileUsingGAIAAvatar,
base::BindRepeating(&ProfileImpl::UpdateAvatarInStorage,
base::Unretained(this)));
// Changes in the profile name.
pref_change_registrar_.Add(
prefs::kProfileUsingDefaultName,
base::BindRepeating(&ProfileImpl::UpdateNameInStorage,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kProfileName,
base::BindRepeating(&ProfileImpl::UpdateNameInStorage,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kForceEphemeralProfiles,
base::BindRepeating(&ProfileImpl::UpdateIsEphemeralInStorage,
base::Unretained(this)));
media_device_id_salt_ = new MediaDeviceIDSalt(prefs_.get());
base::FilePath base_cache_path;
// It would be nice to use PathService for fetching this directory, but
// the cache directory depends on the profile directory, which isn't available
// to PathService.
chrome::GetUserCacheDirectory(path_, &base_cache_path);
// Always create the cache directory asynchronously.
CreateProfileDirectory(io_task_runner_.get(), base_cache_path, false);
// Initialize components that depend on the current value.
UpdateSupervisedUserIdInStorage();
UpdateIsEphemeralInStorage();
GAIAInfoUpdateServiceFactory::GetForProfile(this);
#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
// Initialize the BackgroundModeManager - this has to be done here before
// InitExtensions() is called because it relies on receiving notifications
// when extensions are loaded. BackgroundModeManager is not needed under
// ChromeOS because Chrome is always running, no need for special keep-alive
// or launch-on-startup support unless kKeepAliveForTest is set.
bool init_background_mode_manager = true;
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kKeepAliveForTest))
init_background_mode_manager = false;
#endif
if (init_background_mode_manager) {
if (g_browser_process->background_mode_manager())
g_browser_process->background_mode_manager()->RegisterProfile(this);
}
#endif // BUILDFLAG(ENABLE_BACKGROUND_MODE)
#if BUILDFLAG(ENABLE_PLUGINS)
ChromePluginServiceFilter::GetInstance()->RegisterProfile(this);
#endif
auto* db_provider = GetDefaultStoragePartition()->GetProtoDatabaseProvider();
key_->SetProtoDatabaseProvider(db_provider);
// The DomDistillerViewerSource is not a normal WebUI so it must be registered
// as a URLDataSource early.
dom_distiller::RegisterViewerSource(this);
#if BUILDFLAG(IS_CHROMEOS_ASH)
MigrateSigninScopedDeviceId(this);
if (ash::UserSessionManager::GetInstance()
->RestartToApplyPerSessionFlagsIfNeed(this, true)) {
return;
}
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH)
// Listen for bookmark model load, to bootstrap the sync service.
// On CrOS sync service will be initialized after sign in.
BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(this);
model->AddObserver(new BookmarkModelLoadedObserver(this));
#endif
HeavyAdServiceFactory::GetForBrowserContext(this)->Initialize(GetPath());
PushMessagingServiceImpl::InitializeForProfile(this);
#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
signin_ui_util::InitializePrefsForProfile(this);
#endif
site_isolation::SiteIsolationPolicy::ApplyPersistedIsolatedOrigins(this);
InitializeDataReductionProxy();
content::URLDataSource::Add(this,
std::make_unique<PrefsInternalsSource>(this));
#if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
if (IsNewProfile()) {
// The installed Windows language packs aren't determined until
// the spellcheck service is initialized. Make sure the primary
// preferred language is enabled for spellchecking until the user
// opts out later. If there is no dictionary support for the language
// then it will later be automatically disabled.
SpellcheckService::EnableFirstUserLanguageForSpellcheck(prefs_.get());
}
#endif
if (delegate_) {
TRACE_EVENT0("browser",
"ProfileImpl::DoFinalInit:DelegateOnProfileCreationFinished");
// Fails if the browser is shutting down. This is done to avoid
// launching new UI, finalising profile creation, etc. which
// would trigger a crash down the line. See ...
const bool shutting_down = g_browser_process->IsShuttingDown();
delegate_->OnProfileCreationFinished(this, create_mode, !shutting_down,
IsNewProfile());
// The current Profile may be immediately deleted as part of
// the call to OnProfileCreationFinished(...) if the initialisation is
// reported as a failure, thus no code should be executed past
// that point.
if (shutting_down)
return;
}
SharingServiceFactory::GetForBrowserContext(this);
// The creation of FlocIdProvider should align with the start of a browser
// profile session, so initialize it here.
federated_learning::FlocIdProviderFactory::GetForProfile(this);
AnnouncementNotificationServiceFactory::GetForProfile(this)
->MaybeShowNotification();
}
base::FilePath ProfileImpl::last_selected_directory() {
return GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory);
}
void ProfileImpl::set_last_selected_directory(const base::FilePath& path) {
GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory, path);
}
ProfileImpl::~ProfileImpl() {
MaybeSendDestroyedNotification();
bool prefs_loaded = prefs_->GetInitializationStatus() !=
PrefService::INITIALIZATION_STATUS_WAITING;
#if BUILDFLAG(ENABLE_SESSION_SERVICE)
StopCreateSessionServiceTimer();
#endif
// Remove pref observers
pref_change_registrar_.RemoveAll();
#if BUILDFLAG(ENABLE_PLUGINS)
ChromePluginServiceFilter::GetInstance()->UnregisterProfile(this);
#endif
// Destroy all OTR profiles and their profile services first.
std::vector<Profile*> raw_otr_profiles;
bool primary_otr_available = false;
// Get a list of existing OTR profiles since |off_the_record_profile_| might
// be modified after the call to |DestroyProfileNow|.
for (auto& otr_profile : otr_profiles_) {
raw_otr_profiles.push_back(otr_profile.second.get());
primary_otr_available |= (otr_profile.first == OTRProfileID::PrimaryID());
}
for (Profile* otr_profile : raw_otr_profiles)
ProfileDestroyer::DestroyOffTheRecordProfileNow(otr_profile);
#if BUILDFLAG(ENABLE_EXTENSIONS)
if (!primary_otr_available) {
ExtensionPrefValueMapFactory::GetForBrowserContext(this)
->ClearAllIncognitoSessionOnlyPreferences();
}
#endif
FullBrowserTransitionManager::Get()->OnProfileDestroyed(this);
// The SimpleDependencyManager should always be passed after the
// BrowserContextDependencyManager. This is because the KeyedService instances
// in the BrowserContextDependencyManager's dependency graph can depend on the
// ones in the SimpleDependencyManager's graph.
DependencyManager::PerformInterlockedTwoPhaseShutdown(
BrowserContextDependencyManager::GetInstance(), this,
SimpleDependencyManager::GetInstance(), key_.get());
SimpleKeyMap::GetInstance()->Dissociate(this);
profile_policy_connector_->Shutdown();
if (configuration_policy_provider())
configuration_policy_provider()->Shutdown();
// This causes the Preferences file to be written to disk.
if (prefs_loaded)
SetExitType(EXIT_NORMAL);
// This must be called before ProfileIOData::ShutdownOnUIThread but after
// other profile-related destroy notifications are dispatched.
ShutdownStoragePartitions();
}
std::string ProfileImpl::GetProfileUserName() const {
const signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfileIfExists(this);
if (identity_manager) {
return identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync)
.email;
}
return std::string();
}
#if !defined(OS_ANDROID)
std::unique_ptr<content::ZoomLevelDelegate>
ProfileImpl::CreateZoomLevelDelegate(const base::FilePath& partition_path) {
return std::make_unique<ChromeZoomLevelPrefs>(
GetPrefs(), GetPath(), partition_path,
zoom::ZoomEventManager::GetForBrowserContext(this)->GetWeakPtr());
}
#endif // !defined(OS_ANDROID)
base::FilePath ProfileImpl::GetPath() {
return path_;
}
base::FilePath ProfileImpl::GetPath() const {
return path_;
}
base::Time ProfileImpl::GetCreationTime() const {
return prefs_->GetTime(prefs::kProfileCreationTime);
}
scoped_refptr<base::SequencedTaskRunner> ProfileImpl::GetIOTaskRunner() {
return io_task_runner_;
}
bool ProfileImpl::IsOffTheRecord() {
return false;
}
bool ProfileImpl::IsOffTheRecord() const {
return false;
}
#if BUILDFLAG(IS_CHROMEOS_LACROS)
bool ProfileImpl::IsMainProfile() const {
// Profile must be at "Default" path.
// `IdentityManager' will guarantee that the Chrome OS Device Account is
// signed into `this' Profile, if it's the Main Profile.
return Profile::IsMainProfilePath(GetPath());
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
const Profile::OTRProfileID& ProfileImpl::GetOTRProfileID() const {
NOTREACHED();
static base::NoDestructor<OTRProfileID> otr_profile_id(
OTRProfileID::CreateUnique("ProfileImp::NoOTRProfileID"));
return *otr_profile_id;
}
Profile* ProfileImpl::GetOffTheRecordProfile(const OTRProfileID& otr_profile_id,
bool create_if_needed) {
if (HasOffTheRecordProfile(otr_profile_id))
return otr_profiles_[otr_profile_id].get();
if (!create_if_needed)
return nullptr;
// Create a new OffTheRecordProfile
std::unique_ptr<Profile> otr_profile =
Profile::CreateOffTheRecordProfile(this, otr_profile_id);
Profile* raw_otr_profile = otr_profile.get();
otr_profiles_[otr_profile_id] = std::move(otr_profile);
NotifyOffTheRecordProfileCreated(raw_otr_profile);
return raw_otr_profile;
}
std::vector<Profile*> ProfileImpl::GetAllOffTheRecordProfiles() {
std::vector<Profile*> raw_otr_profiles;
for (auto& otr : otr_profiles_)
raw_otr_profiles.push_back(otr.second.get());
return raw_otr_profiles;
}
void ProfileImpl::DestroyOffTheRecordProfile(Profile* otr_profile) {
CHECK(otr_profile);
OTRProfileID profile_id = otr_profile->GetOTRProfileID();
DCHECK(HasOffTheRecordProfile(profile_id));
otr_profiles_.erase(profile_id);
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Extensions are only supported on primary OTR profile.
if (profile_id == OTRProfileID::PrimaryID()) {
ExtensionPrefValueMapFactory::GetForBrowserContext(this)
->ClearAllIncognitoSessionOnlyPreferences();
}
#endif
}
bool ProfileImpl::HasOffTheRecordProfile(const OTRProfileID& otr_profile_id) {
return base::Contains(otr_profiles_, otr_profile_id);
}
bool ProfileImpl::HasAnyOffTheRecordProfile() {
return !otr_profiles_.empty();
}
Profile* ProfileImpl::GetOriginalProfile() {
return this;
}
const Profile* ProfileImpl::GetOriginalProfile() const {
return this;
}
bool ProfileImpl::IsSupervised() const {
return !GetPrefs()->GetString(prefs::kSupervisedUserId).empty();
}
bool ProfileImpl::IsChild() const {
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
return GetPrefs()->GetString(prefs::kSupervisedUserId) ==
supervised_users::kChildAccountSUID;
#else
return false;
#endif
}
bool ProfileImpl::AllowsBrowserWindows() const {
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (chromeos::ProfileHelper::IsSigninProfile(this) ||
chromeos::ProfileHelper::IsLockScreenAppProfile(this)) {
return false;
}
#endif
return !IsSystemProfile();
}
ExtensionSpecialStoragePolicy* ProfileImpl::GetExtensionSpecialStoragePolicy() {
#if BUILDFLAG(ENABLE_EXTENSIONS)
if (!extension_special_storage_policy_.get()) {
TRACE_EVENT0("browser", "ProfileImpl::GetExtensionSpecialStoragePolicy");
extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(
CookieSettingsFactory::GetForProfile(this).get());
}
return extension_special_storage_policy_.get();
#else
return NULL;
#endif
}
void ProfileImpl::OnLocaleReady(CreateMode create_mode) {
TRACE_EVENT0("browser", "ProfileImpl::OnLocaleReady");
// Migrate obsolete prefs.
MigrateObsoleteProfilePrefs(this);
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Note: Extension preferences can be keyed off the extension ID, so need to
// be handled specially (rather than directly as part of
// MigrateObsoleteProfilePrefs()).
extensions::ExtensionPrefs::Get(this)->MigrateObsoleteExtensionPrefs();
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
// If this is a kiosk profile, reset some of its prefs which should not
// persist between sessions.
if (chrome::IsRunningInForcedAppMode()) {
ash::ResetEphemeralKioskPreferences(prefs_.get());
}
#endif
last_session_exit_type_ = SessionTypePrefValueToExitType(
prefs_->GetString(prefs::kSessionExitType));
// Mark the session as open.
prefs_->SetString(prefs::kSessionExitType, kPrefExitTypeCrashed);
g_browser_process->profile_manager()->InitProfileUserPrefs(this);
#if BUILDFLAG(IS_CHROMEOS_ASH)
arc::ArcServiceLauncher::Get()->MaybeSetProfile(this);
#endif
FullBrowserTransitionManager::Get()->OnProfileCreated(this);
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
this);
ChromeVersionService::OnProfileLoaded(prefs_.get(), IsNewProfile());
DoFinalInit(create_mode);
}
void ProfileImpl::OnPrefsLoaded(CreateMode create_mode, bool success) {
TRACE_EVENT0("browser", "ProfileImpl::OnPrefsLoaded");
if (!success) {
if (delegate_)
delegate_->OnProfileCreationFinished(this, create_mode, false, false);
return;
}
// Fail fast if the browser is shutting down. We want to avoid launching new
// UI, finalising profile creation, etc. which would trigger a crash down the
// the line. See crbug.com/625646
if (g_browser_process->IsShuttingDown()) {
if (delegate_)
delegate_->OnProfileCreationFinished(this, create_mode, false, false);
return;
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (create_mode == CREATE_MODE_SYNCHRONOUS) {
// Synchronous create mode implies that either it is restart after crash,
// or we are in tests. In both cases the first loaded locale is correct.
OnLocaleReady(create_mode);
} else {
ash::UserSessionManager::GetInstance()->RespectLocalePreferenceWrapper(
this, base::BindOnce(&ProfileImpl::OnLocaleReady,
base::Unretained(this), create_mode));
}
#else
OnLocaleReady(create_mode);
#endif
}
bool ProfileImpl::WasCreatedByVersionOrLater(const std::string& version) {
base::Version profile_version(ChromeVersionService::GetVersion(prefs_.get()));
base::Version arg_version(version);
return (profile_version.CompareTo(arg_version) >= 0);
}
void ProfileImpl::SetExitType(ExitType exit_type) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (chromeos::ProfileHelper::IsSigninProfile(this))
return;
#endif
if (!prefs_)
return;
ExitType current_exit_type = SessionTypePrefValueToExitType(
prefs_->GetString(prefs::kSessionExitType));
// This may be invoked multiple times during shutdown. Only persist the value
// first passed in (unless it's a reset to the crash state, which happens when
// foregrounding the app on mobile).
if (exit_type == EXIT_CRASHED || current_exit_type == EXIT_CRASHED) {
prefs_->SetString(prefs::kSessionExitType,
ExitTypeToSessionTypePrefValue(exit_type));
}
}
Profile::ExitType ProfileImpl::GetLastSessionExitType() const {
// last_session_exited_cleanly_ is set when the preferences are loaded. Force
// it to be set by asking for the prefs.
GetPrefs();
return last_session_exit_type_;
}
bool ProfileImpl::ShouldRestoreOldSessionCookies() const {
#if defined(OS_ANDROID)
SessionStartupPref::Type startup_pref_type =
SessionStartupPref::GetDefaultStartupType();
#else
SessionStartupPref::Type startup_pref_type =
StartupBrowserCreator::GetSessionStartupPref(
*base::CommandLine::ForCurrentProcess(), this)
.type;
#endif
return GetLastSessionExitType() == Profile::EXIT_CRASHED ||
startup_pref_type == SessionStartupPref::LAST;
}
bool ProfileImpl::ShouldPersistSessionCookies() const {
return true;
}
PrefService* ProfileImpl::GetPrefs() {
return const_cast<PrefService*>(
static_cast<const ProfileImpl*>(this)->GetPrefs());
}
const PrefService* ProfileImpl::GetPrefs() const {
DCHECK(prefs_); // Should explicitly be initialized.
return prefs_.get();
}
#if !defined(OS_ANDROID)
ChromeZoomLevelPrefs* ProfileImpl::GetZoomLevelPrefs() {
return static_cast<ChromeZoomLevelPrefs*>(
GetDefaultStoragePartition()->GetZoomLevelDelegate());
}
#endif // !defined(OS_ANDROID)
// TODO(crbug.com/734484): Remove this function.
PrefService* ProfileImpl::GetReadOnlyOffTheRecordPrefs() {
if (!dummy_otr_prefs_) {
dummy_otr_prefs_ = CreateIncognitoPrefServiceSyncable(
prefs_.get(), CreateExtensionPrefStore(this, true));
}
return dummy_otr_prefs_.get();
}
policy::SchemaRegistryService* ProfileImpl::GetPolicySchemaRegistryService() {
return schema_registry_service_.get();
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
policy::UserCloudPolicyManagerAsh* ProfileImpl::GetUserCloudPolicyManagerAsh() {
return user_cloud_policy_manager_ash_.get();
}
policy::ActiveDirectoryPolicyManager*
ProfileImpl::GetActiveDirectoryPolicyManager() {
return active_directory_policy_manager_.get();
}
#else
policy::UserCloudPolicyManager* ProfileImpl::GetUserCloudPolicyManager() {
return user_cloud_policy_manager_.get();
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
policy::ConfigurationPolicyProvider*
ProfileImpl::configuration_policy_provider() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (user_cloud_policy_manager_ash_)
return user_cloud_policy_manager_ash_.get();
if (active_directory_policy_manager_)
return active_directory_policy_manager_.get();
return nullptr;
#else // !BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_CHROMEOS_LACROS)
if (user_policy_provider_)
return user_policy_provider_.get();
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
return user_cloud_policy_manager_.get();
#endif
}
policy::ProfilePolicyConnector* ProfileImpl::GetProfilePolicyConnector() {
return profile_policy_connector_.get();
}
const policy::ProfilePolicyConnector* ProfileImpl::GetProfilePolicyConnector()
const {
return profile_policy_connector_.get();
}
scoped_refptr<network::SharedURLLoaderFactory>
ProfileImpl::GetURLLoaderFactory() {
return GetDefaultStoragePartition()->GetURLLoaderFactoryForBrowserProcess();
}
content::BrowserPluginGuestManager* ProfileImpl::GetGuestManager() {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return guest_view::GuestViewManager::FromBrowserContext(this);
#else
return NULL;
#endif
}
DownloadManagerDelegate* ProfileImpl::GetDownloadManagerDelegate() {
return DownloadCoreServiceFactory::GetForBrowserContext(this)
->GetDownloadManagerDelegate();
}
storage::SpecialStoragePolicy* ProfileImpl::GetSpecialStoragePolicy() {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return GetExtensionSpecialStoragePolicy();
#else
return NULL;
#endif
}
content::PushMessagingService* ProfileImpl::GetPushMessagingService() {
return PushMessagingServiceFactory::GetForProfile(this);
}
content::StorageNotificationService*
ProfileImpl::GetStorageNotificationService() {
#if defined(OS_ANDROID)
return nullptr;
#else
return StorageNotificationServiceFactory::GetForBrowserContext(this);
#endif
}
content::SSLHostStateDelegate* ProfileImpl::GetSSLHostStateDelegate() {
return StatefulSSLHostStateDelegateFactory::GetForProfile(this);
}
content::BrowsingDataRemoverDelegate*
ProfileImpl::GetBrowsingDataRemoverDelegate() {
return ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(this);
}
// TODO(mlamouri): we should all these BrowserContext implementation to Profile
// instead of repeating them inside all Profile implementations.
content::PermissionControllerDelegate*
ProfileImpl::GetPermissionControllerDelegate() {
return PermissionManagerFactory::GetForProfile(this);
}
content::ClientHintsControllerDelegate*
ProfileImpl::GetClientHintsControllerDelegate() {
return ClientHintsFactory::GetForBrowserContext(this);
}
content::BackgroundFetchDelegate* ProfileImpl::GetBackgroundFetchDelegate() {
return BackgroundFetchDelegateFactory::GetForProfile(this);
}
content::BackgroundSyncController* ProfileImpl::GetBackgroundSyncController() {
return BackgroundSyncControllerFactory::GetForProfile(this);
}
content::ContentIndexProvider* ProfileImpl::GetContentIndexProvider() {
return ContentIndexProviderFactory::GetForProfile(this);
}
content::FederatedIdentityRequestPermissionContextDelegate*
ProfileImpl::GetFederatedIdentityRequestPermissionContext() {
return FederatedIdentityRequestPermissionContextFactory::GetForProfile(this);
}
content::FederatedIdentitySharingPermissionContextDelegate*
ProfileImpl::GetFederatedIdentitySharingPermissionContext() {
return FederatedIdentitySharingPermissionContextFactory::GetForProfile(this);
}
std::string ProfileImpl::GetMediaDeviceIDSalt() {
return media_device_id_salt_->GetSalt();
}
download::InProgressDownloadManager*
ProfileImpl::RetriveInProgressDownloadManager() {
return DownloadManagerUtils::RetrieveInProgressDownloadManager(this);
}
content::FileSystemAccessPermissionContext*
ProfileImpl::GetFileSystemAccessPermissionContext() {
return FileSystemAccessPermissionContextFactory::GetForProfile(this);
}
bool ProfileImpl::IsSameOrParent(Profile* profile) {
return profile && profile->GetOriginalProfile() == this;
}
base::Time ProfileImpl::GetStartTime() const {
return start_time_;
}
ProfileKey* ProfileImpl::GetProfileKey() const {
DCHECK(key_);
return key_.get();
}
#if BUILDFLAG(ENABLE_SESSION_SERVICE)
void ProfileImpl::StopCreateSessionServiceTimer() {
create_session_service_timer_.Stop();
}
void ProfileImpl::EnsureSessionServiceCreated() {
SessionServiceFactory::GetForProfile(this);
}
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
void ProfileImpl::ChangeAppLocale(const std::string& new_locale,
AppLocaleChangedVia via) {
if (new_locale.empty()) {
NOTREACHED();
return;
}
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
if (local_state->IsManagedPreference(language::prefs::kApplicationLocale))
return;
std::string pref_locale =
GetPrefs()->GetString(language::prefs::kApplicationLocale);
language::ConvertToActualUILocale(&pref_locale);
bool do_update_pref = true;
switch (via) {
case APP_LOCALE_CHANGED_VIA_SETTINGS:
case APP_LOCALE_CHANGED_VIA_REVERT: {
// We keep kApplicationLocaleBackup value as a reference. In case value
// of kApplicationLocale preference would change due to sync from other
// device then kApplicationLocaleBackup value will trigger and allow us to
// show notification about automatic locale change in LocaleChangeGuard.
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, new_locale);
GetPrefs()->ClearPref(prefs::kApplicationLocaleAccepted);
// We maintain kApplicationLocale property in both a global storage
// and user's profile. Global property determines locale of login screen,
// while user's profile determines their personal locale preference.
break;
}
case APP_LOCALE_CHANGED_VIA_LOGIN:
case APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN: {
if (!pref_locale.empty()) {
DCHECK(LocaleNotChanged(pref_locale, new_locale));
if (!locale_change_guard_) {
locale_change_guard_ =
std::make_unique<chromeos::LocaleChangeGuard>(this);
}
locale_change_guard_->set_locale_changed_during_login(true);
std::string accepted_locale =
GetPrefs()->GetString(prefs::kApplicationLocaleAccepted);
if (accepted_locale == new_locale) {
// If locale is accepted then we do not want to show LocaleChange
// notification. This notification is triggered by different values
// of kApplicationLocaleBackup and kApplicationLocale preferences,
// so make them identical.
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, new_locale);
} else {
// Back up locale of login screen.
std::string cur_locale = g_browser_process->GetApplicationLocale();
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, cur_locale);
locale_change_guard_->PrepareChangingLocale(cur_locale, new_locale);
}
} else {
std::string cur_locale = g_browser_process->GetApplicationLocale();
std::string backup_locale =
GetPrefs()->GetString(prefs::kApplicationLocaleBackup);
// Profile synchronization takes time and is not completed at that
// moment at first login. So we initialize locale preference in steps:
// (1) first save it to temporary backup;
// (2) on next login we assume that synchronization is already completed
// and we may finalize initialization.
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, cur_locale);
if (!new_locale.empty())
GetPrefs()->SetString(language::prefs::kApplicationLocale,
new_locale);
else if (!backup_locale.empty())
GetPrefs()->SetString(language::prefs::kApplicationLocale,
backup_locale);
do_update_pref = false;
}
break;
}
case APP_LOCALE_CHANGED_VIA_POLICY: {
// If the locale change has been triggered by policy, the original locale
// is not allowed and can't be switched back to.
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, new_locale);
break;
}
case APP_LOCALE_CHANGED_VIA_UNKNOWN:
default: {
NOTREACHED();
break;
}
}
if (do_update_pref)
GetPrefs()->SetString(language::prefs::kApplicationLocale, new_locale);
if (via != APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN)
local_state->SetString(language::prefs::kApplicationLocale, new_locale);
if (user_manager::UserManager::Get()->GetOwnerAccountId() ==
chromeos::ProfileHelper::Get()->GetUserByProfile(this)->GetAccountId())
local_state->SetString(prefs::kOwnerLocale, new_locale);
}
void ProfileImpl::OnLogin() {
if (!locale_change_guard_)
locale_change_guard_ = std::make_unique<chromeos::LocaleChangeGuard>(this);
locale_change_guard_->OnLogin();
}
void ProfileImpl::InitChromeOSPreferences() {
chromeos_preferences_ = std::make_unique<chromeos::Preferences>();
chromeos_preferences_->Init(
this, chromeos::ProfileHelper::Get()->GetUserByProfile(this));
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
bool ProfileImpl::IsNewProfile() const {
#if !defined(OS_ANDROID)
// The profile is new if the preference files has just been created, except on
// first run, because the installer may create a preference file. See
// https://crbug.com/728402
if (first_run::IsChromeFirstRun())
return true;
#endif
return GetPrefs()->GetInitializationStatus() ==
PrefService::INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
}
void ProfileImpl::SetCreationTimeForTesting(base::Time creation_time) {
prefs_->SetTime(prefs::kProfileCreationTime, creation_time);
}
bool ProfileImpl::IsSignedIn() {
signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(this);
return identity_manager &&
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync);
}
GURL ProfileImpl::GetHomePage() {
// --homepage overrides any preferences.
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kHomePage)) {
// TODO(evanm): clean up usage of DIR_CURRENT.
// http://code.google.com/p/chromium/issues/detail?id=60630
// For now, allow this code to call getcwd().
base::ThreadRestrictions::ScopedAllowIO allow_io;
base::FilePath browser_directory;
base::PathService::Get(base::DIR_CURRENT, &browser_directory);
GURL home_page(url_formatter::FixupRelativeFile(
browser_directory,
command_line.GetSwitchValuePath(switches::kHomePage)));
if (home_page.is_valid())
return home_page;
}
if (GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
return GURL(chrome::kChromeUINewTabURL);
GURL home_page(url_formatter::FixupURL(
GetPrefs()->GetString(prefs::kHomePage), std::string()));
if (!home_page.is_valid())
return GURL(chrome::kChromeUINewTabURL);
return home_page;
}
void ProfileImpl::UpdateSupervisedUserIdInStorage() {
ProfileManager* profile_manager = g_browser_process->profile_manager();
ProfileAttributesEntry* entry = profile_manager->GetProfileAttributesStorage()
.GetProfileAttributesWithPath(GetPath());
if (entry)
entry->SetSupervisedUserId(GetPrefs()->GetString(prefs::kSupervisedUserId));
}
void ProfileImpl::UpdateNameInStorage() {
ProfileAttributesEntry* entry = g_browser_process->profile_manager()
->GetProfileAttributesStorage()
.GetProfileAttributesWithPath(GetPath());
if (entry) {
entry->SetLocalProfileName(
base::UTF8ToUTF16(GetPrefs()->GetString(prefs::kProfileName)),
GetPrefs()->GetBoolean(prefs::kProfileUsingDefaultName));
}
}
void ProfileImpl::UpdateAvatarInStorage() {
ProfileAttributesEntry* entry = g_browser_process->profile_manager()
->GetProfileAttributesStorage()
.GetProfileAttributesWithPath(GetPath());
if (entry) {
entry->SetAvatarIconIndex(
GetPrefs()->GetInteger(prefs::kProfileAvatarIndex));
entry->SetIsUsingDefaultAvatar(
GetPrefs()->GetBoolean(prefs::kProfileUsingDefaultAvatar));
entry->SetIsUsingGAIAPicture(
GetPrefs()->GetBoolean(prefs::kProfileUsingGAIAAvatar));
}
}
void ProfileImpl::UpdateIsEphemeralInStorage() {
ProfileAttributesEntry* entry = g_browser_process->profile_manager()
->GetProfileAttributesStorage()
.GetProfileAttributesWithPath(GetPath());
// If a profile is omitted, it has to be ephemeral and thus setting the value
// based on the pref does not make any sense. Whenever the profile is set as
// non-omitted, it should also update IsEphemeral to respect this pref.
if (entry && !entry->IsOmitted()) {
entry->SetIsEphemeral(
GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles));
}
}
void ProfileImpl::InitializeDataReductionProxy() {
scoped_refptr<base::SequencedTaskRunner> db_task_runner =
base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
std::unique_ptr<data_reduction_proxy::DataStore> store(
new data_reduction_proxy::DataStoreImpl(GetPath()));
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(this)
->InitDataReductionProxySettings(this, std::move(store), db_task_runner);
}