blob: 8f7545bea8de22b16f8463bc014025bfef974592 [file] [log] [blame]
// Copyright 2018 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/renderer_updater.h"
#include <utility>
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/renderer_configuration.mojom.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "extensions/buildflags/buildflags.h"
#include "services/network/public/cpp/features.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/signin/merge_session_throttling_utils.h"
#include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
#endif
namespace {
#if BUILDFLAG(ENABLE_EXTENSIONS)
// By default, JavaScript, images and autoplay are enabled in guest content.
void GetGuestViewDefaultContentSettingRules(
bool incognito,
RendererContentSettingRules* rules) {
rules->image_rules.push_back(ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
base::Value::FromUniquePtrValue(
content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW)),
std::string(), incognito));
rules->script_rules.push_back(ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
base::Value::FromUniquePtrValue(
content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW)),
std::string(), incognito));
rules->autoplay_rules.push_back(ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
base::Value::FromUniquePtrValue(
content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW)),
std::string(), incognito));
rules->client_hints_rules.push_back(ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
base::Value::FromUniquePtrValue(
content_settings::ContentSettingToValue(CONTENT_SETTING_BLOCK)),
std::string(), incognito));
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
} // namespace
RendererUpdater::RendererUpdater(Profile* profile)
: profile_(profile), identity_manager_observer_(this) {
identity_manager_ = IdentityManagerFactory::GetForProfile(profile);
identity_manager_observer_.Add(identity_manager_);
#if defined(OS_CHROMEOS)
oauth2_login_manager_ =
chromeos::OAuth2LoginManagerFactory::GetForProfile(profile_);
oauth2_login_manager_->AddObserver(this);
merge_session_running_ =
merge_session_throttling_utils::ShouldDelayRequestForProfile(profile_);
#endif
variations_http_header_provider_ =
variations::VariationsHttpHeaderProvider::GetInstance();
variations_http_header_provider_->AddObserver(this);
cached_variation_ids_header_ =
variations_http_header_provider_->GetClientDataHeader(
false /* is_signed_in */);
cached_variation_ids_header_signed_in_ =
variations_http_header_provider_->GetClientDataHeader(
true /* is_signed_in */);
PrefService* pref_service = profile->GetPrefs();
force_google_safesearch_.Init(prefs::kForceGoogleSafeSearch, pref_service);
force_youtube_restrict_.Init(prefs::kForceYouTubeRestrict, pref_service);
allowed_domains_for_apps_.Init(prefs::kAllowedDomainsForApps, pref_service);
pref_change_registrar_.Init(pref_service);
pref_change_registrar_.Add(
prefs::kForceGoogleSafeSearch,
base::BindRepeating(&RendererUpdater::UpdateAllRenderers,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kForceYouTubeRestrict,
base::BindRepeating(&RendererUpdater::UpdateAllRenderers,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kAllowedDomainsForApps,
base::BindRepeating(&RendererUpdater::UpdateAllRenderers,
base::Unretained(this)));
}
RendererUpdater::~RendererUpdater() {
DCHECK(!identity_manager_);
#if defined(OS_CHROMEOS)
DCHECK(!oauth2_login_manager_);
#endif
}
void RendererUpdater::Shutdown() {
#if defined(OS_CHROMEOS)
oauth2_login_manager_->RemoveObserver(this);
oauth2_login_manager_ = nullptr;
#endif
identity_manager_observer_.RemoveAll();
identity_manager_ = nullptr;
variations_http_header_provider_->RemoveObserver(this);
variations_http_header_provider_ = nullptr;
}
void RendererUpdater::InitializeRenderer(
content::RenderProcessHost* render_process_host) {
auto renderer_configuration = GetRendererConfiguration(render_process_host);
Profile* profile =
Profile::FromBrowserContext(render_process_host->GetBrowserContext());
bool is_incognito_process = profile->IsOffTheRecord();
chrome::mojom::ChromeOSListenerRequest chromeos_listener_request;
#if defined(OS_CHROMEOS)
if (merge_session_running_) {
chrome::mojom::ChromeOSListenerPtr chromeos_listener;
chromeos_listener_request = MakeRequest(&chromeos_listener);
chromeos_listeners_.push_back(std::move(chromeos_listener));
}
#endif // defined(OS_CHROMEOS)
renderer_configuration->SetInitialConfiguration(
is_incognito_process, std::move(chromeos_listener_request));
UpdateRenderer(&renderer_configuration);
RendererContentSettingRules rules;
if (render_process_host->IsForGuestsOnly()) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
GetGuestViewDefaultContentSettingRules(is_incognito_process, &rules);
#else
NOTREACHED();
#endif
} else {
content_settings::GetRendererContentSettingRules(
HostContentSettingsMapFactory::GetForProfile(profile), &rules);
}
renderer_configuration->SetContentSettingRules(rules);
}
std::vector<chrome::mojom::RendererConfigurationAssociatedPtr>
RendererUpdater::GetRendererConfigurations() {
std::vector<chrome::mojom::RendererConfigurationAssociatedPtr> rv;
for (content::RenderProcessHost::iterator it(
content::RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
Profile* renderer_profile =
static_cast<Profile*>(it.GetCurrentValue()->GetBrowserContext());
if (renderer_profile == profile_ ||
renderer_profile->GetOriginalProfile() == profile_) {
auto renderer_configuration =
GetRendererConfiguration(it.GetCurrentValue());
if (renderer_configuration)
rv.push_back(std::move(renderer_configuration));
}
}
return rv;
}
chrome::mojom::RendererConfigurationAssociatedPtr
RendererUpdater::GetRendererConfiguration(
content::RenderProcessHost* render_process_host) {
IPC::ChannelProxy* channel = render_process_host->GetChannel();
if (!channel)
return nullptr;
chrome::mojom::RendererConfigurationAssociatedPtr renderer_configuration;
channel->GetRemoteAssociatedInterface(&renderer_configuration);
return renderer_configuration;
}
#if defined(OS_CHROMEOS)
void RendererUpdater::OnSessionRestoreStateChanged(
Profile* user_profile,
chromeos::OAuth2LoginManager::SessionRestoreState state) {
merge_session_running_ =
merge_session_throttling_utils::ShouldDelayRequestForProfile(profile_);
if (merge_session_running_)
return;
for (auto& chromeos_listener : chromeos_listeners_)
chromeos_listener->MergeSessionComplete();
chromeos_listeners_.clear();
}
#endif
void RendererUpdater::OnPrimaryAccountSet(const AccountInfo& account_info) {
UpdateAllRenderers();
}
void RendererUpdater::OnPrimaryAccountCleared(const AccountInfo& account_info) {
UpdateAllRenderers();
}
void RendererUpdater::VariationIdsHeaderUpdated(
const std::string& variation_ids_header,
const std::string& variation_ids_header_signed_in) {
cached_variation_ids_header_ = variation_ids_header;
cached_variation_ids_header_signed_in_ = variation_ids_header_signed_in;
UpdateAllRenderers();
}
void RendererUpdater::UpdateAllRenderers() {
auto renderer_configurations = GetRendererConfigurations();
for (auto& renderer_configuration : renderer_configurations)
UpdateRenderer(&renderer_configuration);
}
void RendererUpdater::UpdateRenderer(
chrome::mojom::RendererConfigurationAssociatedPtr* renderer_configuration) {
(*renderer_configuration)
->SetConfiguration(chrome::mojom::DynamicParams::New(
force_google_safesearch_.GetValue(),
force_youtube_restrict_.GetValue(),
allowed_domains_for_apps_.GetValue(),
identity_manager_->HasPrimaryAccount()
? cached_variation_ids_header_signed_in_
: cached_variation_ids_header_));
}