[go: nahoru, domu]

blob: 8af3007fc762ff8bd3f7ed70864ba8b3d508fdc7 [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 <span> // std::size.
#include "base/containers/contains.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/pref_mapping.h"
#include "chrome/browser/extensions/pref_transformer_interface.h"
#include "chrome/browser/prefetch/pref_names.h"
#include "chrome/browser/prefetch/prefetch_prefs.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/embedder_support/pref_names.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/privacy_sandbox/privacy_sandbox_prefs.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/spellcheck/browser/pref_names.h"
#include "components/translate/core/browser/translate_pref_names.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/chromeos/extensions/controlled_pref_mapping.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "base/containers/fixed_flat_map.h"
#endif
using extensions::mojom::APIPermissionID;
namespace extensions {
namespace {
constexpr char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange";
const PrefMappingEntry kMappings[] = {
{"alternateErrorPagesEnabled",
embedder_support::kAlternateErrorPagesEnabled, APIPermissionID::kPrivacy,
APIPermissionID::kPrivacy},
{"autofillEnabled", autofill::prefs::kAutofillEnabledDeprecated,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"autofillAddressEnabled", autofill::prefs::kAutofillProfileEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"autofillCreditCardEnabled", autofill::prefs::kAutofillCreditCardEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"hyperlinkAuditingEnabled", prefs::kEnableHyperlinkAuditing,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"networkPredictionEnabled", prefetch::prefs::kNetworkPredictionOptions,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"passwordSavingEnabled",
password_manager::prefs::kCredentialsEnableService,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
// Note in Lacros this is Ash-controlled.
{"protectedContentEnabled", prefs::kProtectedContentDefault,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"proxy", proxy_config::prefs::kProxy, APIPermissionID::kProxy,
APIPermissionID::kProxy},
{"referrersEnabled", prefs::kEnableReferrers, APIPermissionID::kPrivacy,
APIPermissionID::kPrivacy},
{"doNotTrackEnabled", prefs::kEnableDoNotTrack, APIPermissionID::kPrivacy,
APIPermissionID::kPrivacy},
{"safeBrowsingEnabled", prefs::kSafeBrowsingEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"safeBrowsingExtendedReportingEnabled",
prefs::kSafeBrowsingScoutReportingEnabled, APIPermissionID::kPrivacy,
APIPermissionID::kPrivacy},
{"searchSuggestEnabled", prefs::kSearchSuggestEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"spellingServiceEnabled", spellcheck::prefs::kSpellCheckUseSpellingService,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"thirdPartyCookiesAllowed", prefs::kCookieControlsMode,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"privacySandboxEnabled", prefs::kPrivacySandboxApisEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"topicsEnabled", prefs::kPrivacySandboxM1TopicsEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"fledgeEnabled", prefs::kPrivacySandboxM1FledgeEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"adMeasurementEnabled", prefs::kPrivacySandboxM1AdMeasurementEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"translationServiceEnabled", translate::prefs::kOfferTranslateEnabled,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"webRTCIPHandlingPolicy", prefs::kWebRTCIPHandlingPolicy,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
{"webRTCUDPPortRange", prefs::kWebRTCUDPPortRange,
APIPermissionID::kPrivacy, APIPermissionID::kPrivacy},
// accessibilityFeatures.animationPolicy is available for
// all platforms but the others from accessibilityFeatures
// is only available for OS_CHROMEOS.
{"animationPolicy", prefs::kAnimationPolicy,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
// Below is the list of extension-controlled preferences where the underlying
// feature being controlled exists in ash. They should be kept in sync/in order.
// If a new extension-controlled pref of this type is added, it should be added
// to both lists.
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
{"autoclick", chromeos::prefs::kAccessibilityAutoclickEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"caretHighlight", chromeos::prefs::kAccessibilityCaretHighlightEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"cursorColor", chromeos::prefs::kAccessibilityCursorColorEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"cursorHighlight", chromeos::prefs::kAccessibilityCursorHighlightEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"dictation", chromeos::prefs::kAccessibilityDictationEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"dockedMagnifier", chromeos::prefs::kDockedMagnifierEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"focusHighlight", chromeos::prefs::kAccessibilityFocusHighlightEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"highContrast", chromeos::prefs::kAccessibilityHighContrastEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"largeCursor", chromeos::prefs::kAccessibilityLargeCursorEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"screenMagnifier", chromeos::prefs::kAccessibilityScreenMagnifierEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"selectToSpeak", chromeos::prefs::kAccessibilitySelectToSpeakEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"spokenFeedback", chromeos::prefs::kAccessibilitySpokenFeedbackEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"stickyKeys", chromeos::prefs::kAccessibilityStickyKeysEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"switchAccess", chromeos::prefs::kAccessibilitySwitchAccessEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
{"virtualKeyboard", chromeos::prefs::kAccessibilityVirtualKeyboardEnabled,
APIPermissionID::kAccessibilityFeaturesRead,
APIPermissionID::kAccessibilityFeaturesModify},
#endif
};
class IdentityPrefTransformer : public PrefTransformerInterface {
public:
absl::optional<base::Value> ExtensionToBrowserPref(
const base::Value& extension_pref,
std::string& error,
bool& bad_message) override {
return extension_pref.Clone();
}
absl::optional<base::Value> BrowserToExtensionPref(
const base::Value& browser_pref,
bool is_incognito_profile) override {
return browser_pref.Clone();
}
};
} // namespace
// static
PrefMapping* PrefMapping::GetInstance() {
return base::Singleton<PrefMapping>::get();
}
// static
base::span<const PrefMappingEntry> PrefMapping::GetMappings() {
return kMappings;
}
bool PrefMapping::FindBrowserPrefForExtensionPref(
const std::string& extension_pref,
std::string* browser_pref,
APIPermissionID* read_permission,
APIPermissionID* write_permission) const {
auto it = mapping_.find(extension_pref);
if (it == mapping_.end())
return false;
*browser_pref = it->second.pref_name;
*read_permission = it->second.read_permission;
*write_permission = it->second.write_permission;
return true;
}
bool PrefMapping::FindEventForBrowserPref(const std::string& browser_pref,
std::string* event_name,
APIPermissionID* permission) const {
auto it = event_mapping_.find(browser_pref);
if (it == event_mapping_.end())
return false;
*event_name = it->second.pref_name;
*permission = it->second.read_permission;
return true;
}
PrefTransformerInterface* PrefMapping::FindTransformerForBrowserPref(
const std::string& browser_pref) const {
auto it = transformers_.find(browser_pref);
if (it != transformers_.end())
return it->second.get();
return identity_transformer_.get();
}
#if BUILDFLAG(IS_CHROMEOS_LACROS)
// Given a pref name for an extension-controlled pref where the underlying
// pref is controlled by ash, returns the PrefPath used by the crosapi to set
// the pref in ash, or nullptr if no pref exists.
crosapi::mojom::PrefPath PrefMapping::GetPrefPathForPrefName(
const std::string& pref_name) const {
static const auto name_to_extension_prefpath = base::MakeFixedFlatMap<
base::StringPiece, crosapi::mojom::PrefPath>(
{{chromeos::prefs::kDockedMagnifierEnabled,
crosapi::mojom::PrefPath::kDockedMagnifierEnabled},
{chromeos::prefs::kAccessibilityAutoclickEnabled,
crosapi::mojom::PrefPath::kAccessibilityAutoclickEnabled},
{chromeos::prefs::kAccessibilityCaretHighlightEnabled,
crosapi::mojom::PrefPath::kAccessibilityCaretHighlightEnabled},
{chromeos::prefs::kAccessibilityCursorColorEnabled,
crosapi::mojom::PrefPath::kAccessibilityCursorColorEnabled},
{chromeos::prefs::kAccessibilityCursorHighlightEnabled,
crosapi::mojom::PrefPath::kAccessibilityCursorHighlightEnabled},
{chromeos::prefs::kAccessibilityDictationEnabled,
crosapi::mojom::PrefPath::kAccessibilityDictationEnabled},
{chromeos::prefs::kAccessibilityFocusHighlightEnabled,
crosapi::mojom::PrefPath::kAccessibilityFocusHighlightEnabled},
{chromeos::prefs::kAccessibilityHighContrastEnabled,
crosapi::mojom::PrefPath::kAccessibilityHighContrastEnabled},
{chromeos::prefs::kAccessibilityLargeCursorEnabled,
crosapi::mojom::PrefPath::kAccessibilityLargeCursorEnabled},
{chromeos::prefs::kAccessibilityScreenMagnifierEnabled,
crosapi::mojom::PrefPath::kAccessibilityScreenMagnifierEnabled},
{chromeos::prefs::kAccessibilitySelectToSpeakEnabled,
crosapi::mojom::PrefPath::kAccessibilitySelectToSpeakEnabled},
{chromeos::prefs::kAccessibilitySpokenFeedbackEnabled,
crosapi::mojom::PrefPath::kExtensionAccessibilitySpokenFeedbackEnabled},
{chromeos::prefs::kAccessibilityStickyKeysEnabled,
crosapi::mojom::PrefPath::kAccessibilityStickyKeysEnabled},
{chromeos::prefs::kAccessibilitySwitchAccessEnabled,
crosapi::mojom::PrefPath::kAccessibilitySwitchAccessEnabled},
{chromeos::prefs::kAccessibilityVirtualKeyboardEnabled,
crosapi::mojom::PrefPath::kAccessibilityVirtualKeyboardEnabled},
{prefs::kProtectedContentDefault,
crosapi::mojom::PrefPath::kProtectedContentDefault}});
auto* pref_iter = name_to_extension_prefpath.find(pref_name);
return pref_iter == name_to_extension_prefpath.end()
? crosapi::mojom::PrefPath::kUnknown
: pref_iter->second;
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
PrefMapping::PrefMapping() {
identity_transformer_ = std::make_unique<IdentityPrefTransformer>();
for (const auto& pref : kMappings) {
mapping_[pref.extension_pref] = PrefMapData(
pref.browser_pref, pref.read_permission, pref.write_permission);
std::string event_name =
base::StringPrintf(kOnPrefChangeFormat, pref.extension_pref);
event_mapping_[pref.browser_pref] =
PrefMapData(event_name, pref.read_permission, pref.write_permission);
}
DCHECK_EQ(std::size(kMappings), mapping_.size());
DCHECK_EQ(std::size(kMappings), event_mapping_.size());
}
PrefMapping::~PrefMapping() = default;
void PrefMapping::RegisterPrefTransformer(
const std::string& browser_pref,
std::unique_ptr<PrefTransformerInterface> transformer) {
DCHECK(!base::Contains(transformers_, browser_pref))
<< "Trying to register pref transformer for " << browser_pref << " twice";
transformers_[browser_pref] = std::move(transformer);
}
} // namespace extensions