// Copyright 2019 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 "weblayer/browser/browser_context_impl.h" #include "base/threading/thread_restrictions.h" #include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" #include "components/client_hints/browser/client_hints.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/download/public/common/in_progress_download_manager.h" #include "components/embedder_support/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/language/core/browser/language_prefs.h" #include "components/permissions/permission_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/in_memory_pref_store.h" #include "components/prefs/json_pref_store.h" #include "components/prefs/pref_service.h" #include "components/prefs/pref_service_factory.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" #include "components/site_isolation/pref_names.h" #include "components/site_isolation/site_isolation_policy.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/user_prefs/user_prefs.h" #include "components/variations/variations_client.h" #include "components/variations/variations_http_header_provider.h" #include "content/public/browser/device_service.h" #include "content/public/browser/download_request_utils.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/storage_partition.h" #include "weblayer/browser/browsing_data_remover_delegate.h" #include "weblayer/browser/browsing_data_remover_delegate_factory.h" #include "weblayer/browser/client_hints_factory.h" #include "weblayer/browser/permissions/permission_manager_factory.h" #include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" #include "weblayer/public/common/switches.h" #if defined(OS_ANDROID) #include "base/android/path_utils.h" #include "components/cdm/browser/media_drm_storage_impl.h" // nogncheck #include "components/permissions/contexts/geolocation_permission_context_android.h" #include "components/unified_consent/pref_names.h" #elif defined(OS_WIN) #include #include #include "base/win/scoped_co_mem.h" #elif defined(OS_POSIX) #include "base/nix/xdg_util.h" #endif namespace weblayer { namespace { // Ignores origin security check. DownloadManagerImpl will provide its own // implementation when InProgressDownloadManager object is passed to it. bool IgnoreOriginSecurityCheck(const GURL& url) { return true; } void BindWakeLockProvider( mojo::PendingReceiver receiver) { content::GetDeviceService().BindWakeLockProvider(std::move(receiver)); } } // namespace namespace prefs { // Used to persist the public SettingType::UKM_ENABLED API. const char kUkmEnabled[] = "weblayer.ukm_enabled"; } // namespace prefs class ResourceContextImpl : public content::ResourceContext { public: ResourceContextImpl() = default; ~ResourceContextImpl() override = default; private: DISALLOW_COPY_AND_ASSIGN(ResourceContextImpl); }; BrowserContextImpl::BrowserContextImpl(ProfileImpl* profile_impl, const base::FilePath& path) : profile_impl_(profile_impl), path_(path), resource_context_(new ResourceContextImpl()), download_delegate_(BrowserContext::GetDownloadManager(this)) { CreateUserPrefService(); BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices( this); site_isolation::SiteIsolationPolicy::ApplyPersistedIsolatedOrigins(this); } BrowserContextImpl::~BrowserContextImpl() { NotifyWillBeDestroyed(this); BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( this); } base::FilePath BrowserContextImpl::GetDefaultDownloadDirectory() { // Note: if we wanted to productionize this on Windows/Linux, refactor // src/chrome's GetDefaultDownloadDirectory. base::FilePath download_dir; #if defined(OS_ANDROID) base::android::GetDownloadsDirectory(&download_dir); #elif defined(OS_WIN) base::win::ScopedCoMem path_buf; if (SUCCEEDED( SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &path_buf))) { download_dir = base::FilePath(path_buf.get()); } else { NOTREACHED(); } #else download_dir = base::nix::GetXDGUserDirectory("DOWNLOAD", "Downloads"); #endif return download_dir; } #if !defined(OS_ANDROID) std::unique_ptr BrowserContextImpl::CreateZoomLevelDelegate(const base::FilePath&) { return nullptr; } #endif // !defined(OS_ANDROID) base::FilePath BrowserContextImpl::GetPath() { return path_; } bool BrowserContextImpl::IsOffTheRecord() { return path_.empty(); } content::DownloadManagerDelegate* BrowserContextImpl::GetDownloadManagerDelegate() { return &download_delegate_; } content::ResourceContext* BrowserContextImpl::GetResourceContext() { return resource_context_.get(); } content::BrowserPluginGuestManager* BrowserContextImpl::GetGuestManager() { return nullptr; } storage::SpecialStoragePolicy* BrowserContextImpl::GetSpecialStoragePolicy() { return nullptr; } content::PushMessagingService* BrowserContextImpl::GetPushMessagingService() { return nullptr; } content::StorageNotificationService* BrowserContextImpl::GetStorageNotificationService() { return nullptr; } content::SSLHostStateDelegate* BrowserContextImpl::GetSSLHostStateDelegate() { return StatefulSSLHostStateDelegateFactory::GetForBrowserContext(this); } content::PermissionControllerDelegate* BrowserContextImpl::GetPermissionControllerDelegate() { return PermissionManagerFactory::GetForBrowserContext(this); } content::ClientHintsControllerDelegate* BrowserContextImpl::GetClientHintsControllerDelegate() { return ClientHintsFactory::GetForBrowserContext(this); } content::BackgroundFetchDelegate* BrowserContextImpl::GetBackgroundFetchDelegate() { return nullptr; } content::BackgroundSyncController* BrowserContextImpl::GetBackgroundSyncController() { return nullptr; } content::BrowsingDataRemoverDelegate* BrowserContextImpl::GetBrowsingDataRemoverDelegate() { return BrowsingDataRemoverDelegateFactory::GetForBrowserContext(this); } download::InProgressDownloadManager* BrowserContextImpl::RetriveInProgressDownloadManager() { // Override this to provide a connection to the wake lock service. auto* download_manager = new download::InProgressDownloadManager( nullptr, path_, path_.empty() ? nullptr : GetDefaultStoragePartition(this)->GetProtoDatabaseProvider(), base::BindRepeating(&IgnoreOriginSecurityCheck), base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe), base::BindRepeating(&BindWakeLockProvider)); #if defined(OS_ANDROID) download_manager->set_default_download_dir(GetDefaultDownloadDirectory()); #endif return download_manager; } content::ContentIndexProvider* BrowserContextImpl::GetContentIndexProvider() { return nullptr; } void BrowserContextImpl::CreateUserPrefService() { auto pref_registry = base::MakeRefCounted(); RegisterPrefs(pref_registry.get()); PrefServiceFactory pref_service_factory; if (IsOffTheRecord()) { pref_service_factory.set_user_prefs( base::MakeRefCounted()); } else { pref_service_factory.set_user_prefs(base::MakeRefCounted( path_.Append(FILE_PATH_LITERAL("Preferences")))); } { // Creating the prefs service may require reading the preferences from disk. base::ScopedAllowBlocking allow_io; user_pref_service_ = pref_service_factory.Create(pref_registry); } // Note: UserPrefs::Set also ensures that the user_pref_service_ has not // been set previously. user_prefs::UserPrefs::Set(this, user_pref_service_.get()); } void BrowserContextImpl::RegisterPrefs( user_prefs::PrefRegistrySyncable* pref_registry) { pref_registry->RegisterBooleanPref(prefs::kUkmEnabled, false); // This pref is used by captive_portal::CaptivePortalService (as well as other // potential use cases in the future, as it is used for various purposes // through //chrome). pref_registry->RegisterBooleanPref( embedder_support::kAlternateErrorPagesEnabled, true); pref_registry->RegisterListPref( site_isolation::prefs::kUserTriggeredIsolatedOrigins); StatefulSSLHostStateDelegate::RegisterProfilePrefs(pref_registry); HostContentSettingsMap::RegisterProfilePrefs(pref_registry); safe_browsing::RegisterProfilePrefs(pref_registry); language::LanguagePrefs::RegisterProfilePrefs(pref_registry); translate::TranslatePrefs::RegisterProfilePrefs(pref_registry); blocked_content::SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs( pref_registry); pref_registry->RegisterBooleanPref( ::prefs::kOfferTranslateEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); #if defined(OS_ANDROID) cdm::MediaDrmStorageImpl::RegisterProfilePrefs(pref_registry); permissions::GeolocationPermissionContextAndroid::RegisterProfilePrefs( pref_registry); pref_registry->RegisterBooleanPref( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false); #endif BrowserContextDependencyManager::GetInstance() ->RegisterProfilePrefsForServices(pref_registry); } class BrowserContextImpl::WebLayerVariationsClient : public variations::VariationsClient { public: explicit WebLayerVariationsClient(content::BrowserContext* browser_context) : browser_context_(browser_context) {} ~WebLayerVariationsClient() override = default; bool IsOffTheRecord() const override { return browser_context_->IsOffTheRecord(); } std::string GetVariationsHeader() const override { return variations::VariationsHttpHeaderProvider::GetInstance() ->GetClientDataHeader(IsSignedIn()); } private: bool IsSignedIn() const { // TODO(weblayer-dev): Update when signin is supported. return false; } content::BrowserContext* browser_context_; }; variations::VariationsClient* BrowserContextImpl::GetVariationsClient() { if (!weblayer_variations_client_) { weblayer_variations_client_ = std::make_unique(this); } return weblayer_variations_client_.get(); } } // namespace weblayer