blob: 769e262ba8486df18e7fb05a6d63a650284bb573 [file] [log] [blame]
// 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 "components/language/core/browser/language_prefs.h"
#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/language/core/browser/pref_names.h"
#include "components/language/core/common/language_util.h"
#include "components/language/core/common/locale_util.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/strings/grit/components_locale_settings.h"
#include "ui/base/l10n/l10n_util.h"
namespace language {
const char kFallbackInputMethodLocale[] = "en-US";
void LanguagePrefs::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterStringPref(language::prefs::kAcceptLanguages,
l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
#if defined(OS_CHROMEOS)
registry->RegisterStringPref(language::prefs::kPreferredLanguages,
kFallbackInputMethodLocale);
registry->RegisterStringPref(language::prefs::kPreferredLanguagesSyncable, "",
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
#endif
registry->RegisterListPref(language::prefs::kFluentLanguages,
LanguagePrefs::GetDefaultFluentLanguages(),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}
LanguagePrefs::LanguagePrefs(PrefService* user_prefs) : prefs_(user_prefs) {
ResetEmptyFluentLanguagesToDefault();
}
bool LanguagePrefs::IsFluent(const std::string& language) const {
std::string canonical_lang = language;
language::ToTranslateLanguageSynonym(&canonical_lang);
const base::Value* fluents =
prefs_->GetList(language::prefs::kFluentLanguages);
return base::Contains(fluents->GetList(), base::Value(canonical_lang));
}
void LanguagePrefs::SetFluent(const std::string& language) {
if (IsFluent(language))
return;
std::string canonical_lang = language;
language::ToTranslateLanguageSynonym(&canonical_lang);
ListPrefUpdate update(prefs_, language::prefs::kFluentLanguages);
update->GetList().emplace_back(std::move(canonical_lang));
}
void LanguagePrefs::ClearFluent(const std::string& language) {
if (NumFluentLanguages() <= 1) // Never remove last fluent language.
return;
std::string canonical_lang = language;
language::ToTranslateLanguageSynonym(&canonical_lang);
ListPrefUpdate update(prefs_, language::prefs::kFluentLanguages);
base::Erase(update->GetList(), base::Value(canonical_lang));
}
void LanguagePrefs::ResetFluentLanguagesToDefaults() {
// Reset pref to defaults.
prefs_->ClearPref(language::prefs::kFluentLanguages);
}
void LanguagePrefs::ResetEmptyFluentLanguagesToDefault() {
if (NumFluentLanguages() == 0)
ResetFluentLanguagesToDefaults();
}
base::Value LanguagePrefs::GetDefaultFluentLanguages() {
std::set<std::string> languages;
#if defined(OS_CHROMEOS)
// Preferred languages.
std::string language = language::kFallbackInputMethodLocale;
language::ToTranslateLanguageSynonym(&language);
languages.insert(std::move(language));
#else
// Accept languages.
for (std::string language :
base::SplitString(l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
language::ToTranslateLanguageSynonym(&language);
languages.insert(std::move(language));
// crbug.com/958348: The default value for Accept-Language *should* be the
// same as the one for Fluent Languages. However, Accept-Language contains
// English (and more) in addition to the local language in most locales due
// to historical reasons. Exiting early from this loop is a temporary fix
// that allows Fluent Languages to be at least populated with the UI
// language while still allowing Translate to trigger on other languages,
// most importantly English.
// Once the change to remove English from Accept-Language defaults lands,
// this break should be removed to enable the Fluent Language List and the
// Accept-Language list to be initialized to the same values.
break;
}
#endif
base::Value language_values(base::Value::Type::LIST);
for (const std::string& language : languages)
language_values.GetList().emplace_back(language);
return language_values;
}
size_t LanguagePrefs::NumFluentLanguages() const {
const base::Value* fluents =
prefs_->GetList(language::prefs::kFluentLanguages);
return fluents->GetList().size();
}
void ResetLanguagePrefs(PrefService* prefs) {
prefs->ClearPref(language::prefs::kAcceptLanguages);
prefs->ClearPref(language::prefs::kFluentLanguages);
#if defined(OS_CHROMEOS)
prefs->ClearPref(language::prefs::kPreferredLanguages);
prefs->ClearPref(language::prefs::kPreferredLanguagesSyncable);
#endif
}
} // namespace language