Commit 088a2961 authored by dilmah@chromium.org's avatar dilmah@chromium.org

Do not use local override for language settings: always store it into synchronized preference.

BUG=chromium-os:11147
TEST=Manual

Review URL: http://codereview.chromium.org/6248017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72633 0039d316-1c4b-4281-b951-d872f2087c98
parent 3b0479c0
...@@ -66,10 +66,8 @@ void LocaleChangeGuard::RevertLocaleChange(const ListValue* list) { ...@@ -66,10 +66,8 @@ void LocaleChangeGuard::RevertLocaleChange(const ListValue* list) {
reverted_ = true; reverted_ = true;
UserMetrics::RecordAction(UserMetricsAction("LanguageChange_Revert")); UserMetrics::RecordAction(UserMetricsAction("LanguageChange_Revert"));
tab_contents_->profile()->ChangeApplicationLocale(from_locale_, true); tab_contents_->profile()->ChangeAppLocale(
prefs->SetString(prefs::kApplicationLocaleBackup, from_locale_); from_locale_, Profile::APP_LOCALE_CHANGED_VIA_REVERT);
prefs->ClearPref(prefs::kApplicationLocaleAccepted);
prefs->ScheduleSavePersistentPrefs();
Browser* browser = Browser::GetBrowserForController( Browser* browser = Browser::GetBrowserForController(
&tab_contents_->controller(), NULL); &tab_contents_->controller(), NULL);
...@@ -88,10 +86,8 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) { ...@@ -88,10 +86,8 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) {
// (1) we want to exit fast in common case when nothing should be done. // (1) we want to exit fast in common case when nothing should be done.
// (2) on ChromeOS this guard may be invoked for a dummy profile first time. // (2) on ChromeOS this guard may be invoked for a dummy profile first time.
ProfileId cur_profile_id = tab_contents->profile()->GetRuntimeId(); ProfileId cur_profile_id = tab_contents->profile()->GetRuntimeId();
if (cur_profile_id == profile_id_) { if (cur_profile_id == profile_id_)
// We have already checked this profile, exiting fast. return; // We have already checked this profile, exiting fast.
return;
}
profile_id_ = cur_profile_id; profile_id_ = cur_profile_id;
std::string cur_locale = g_browser_process->GetApplicationLocale(); std::string cur_locale = g_browser_process->GetApplicationLocale();
...@@ -104,13 +100,7 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) { ...@@ -104,13 +100,7 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) {
if (prefs == NULL) if (prefs == NULL)
return; return;
std::string to_locale = prefs->GetString(prefs::kApplicationLocaleOverride); std::string to_locale = prefs->GetString(prefs::kApplicationLocale);
if (!to_locale.empty()) {
DCHECK(to_locale == cur_locale);
return;
}
to_locale = prefs->GetString(prefs::kApplicationLocale);
if (to_locale != cur_locale) { if (to_locale != cur_locale) {
// This conditional branch can occur in case kApplicationLocale // This conditional branch can occur in case kApplicationLocale
// preference was modified by synchronization. // preference was modified by synchronization.
...@@ -118,10 +108,11 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) { ...@@ -118,10 +108,11 @@ void LocaleChangeGuard::CheckLocaleChange(TabContents* tab_contents) {
} }
std::string from_locale = prefs->GetString(prefs::kApplicationLocaleBackup); std::string from_locale = prefs->GetString(prefs::kApplicationLocaleBackup);
if (from_locale.empty() || from_locale == to_locale) { if (from_locale.empty() || from_locale == to_locale)
// No locale change was detected, just exit. return; // No locale change was detected, just exit.
return;
} if (prefs->GetString(prefs::kApplicationLocaleAccepted) == to_locale)
return; // Already accepted.
// Locale change detected, showing notification. // Locale change detected, showing notification.
from_locale_ = from_locale; from_locale_ = from_locale;
...@@ -160,10 +151,6 @@ void LocaleChangeGuard::AcceptLocaleChange() { ...@@ -160,10 +151,6 @@ void LocaleChangeGuard::AcceptLocaleChange() {
PrefService* prefs = tab_contents_->profile()->GetPrefs(); PrefService* prefs = tab_contents_->profile()->GetPrefs();
if (prefs == NULL) if (prefs == NULL)
return; return;
std::string override_locale =
prefs->GetString(prefs::kApplicationLocaleOverride);
if (!override_locale.empty())
return;
if (prefs->GetString(prefs::kApplicationLocale) != to_locale_) if (prefs->GetString(prefs::kApplicationLocale) != to_locale_)
return; return;
UserMetrics::RecordAction(UserMetricsAction("LanguageChange_Accept")); UserMetrics::RecordAction(UserMetricsAction("LanguageChange_Accept"));
......
...@@ -155,7 +155,7 @@ class LoginUtilsImpl : public LoginUtils { ...@@ -155,7 +155,7 @@ class LoginUtilsImpl : public LoginUtils {
private: private:
// Check user's profile for kApplicationLocale setting. // Check user's profile for kApplicationLocale setting.
void RespectLocalePreference(PrefService* pref); void RespectLocalePreference(Profile* pref);
// Indicates if DoBrowserLaunch will actually launch the browser or not. // Indicates if DoBrowserLaunch will actually launch the browser or not.
bool browser_launch_enabled_; bool browser_launch_enabled_;
...@@ -309,7 +309,7 @@ void LoginUtilsImpl::CompleteLogin( ...@@ -309,7 +309,7 @@ void LoginUtilsImpl::CompleteLogin(
} }
btl->AddLoginTimeMarker("TPMOwned", false); btl->AddLoginTimeMarker("TPMOwned", false);
RespectLocalePreference(profile->GetPrefs()); RespectLocalePreference(profile);
if (first_login) { if (first_login) {
SetFirstLoginPrefs(profile->GetPrefs()); SetFirstLoginPrefs(profile->GetPrefs());
...@@ -354,53 +354,21 @@ void LoginUtilsImpl::FetchTokens( ...@@ -354,53 +354,21 @@ void LoginUtilsImpl::FetchTokens(
} }
} }
void LoginUtilsImpl::RespectLocalePreference(PrefService* prefs) { void LoginUtilsImpl::RespectLocalePreference(Profile* profile) {
DCHECK(profile != NULL);
PrefService* prefs = profile->GetPrefs();
DCHECK(prefs != NULL); DCHECK(prefs != NULL);
std::string pref_locale_override =
prefs->GetString(prefs::kApplicationLocaleOverride);
if (!pref_locale_override.empty()) {
LanguageSwitchMenu::SwitchLanguage(pref_locale_override);
return;
}
if (g_browser_process == NULL) if (g_browser_process == NULL)
return; return;
std::string cur_locale = g_browser_process->GetApplicationLocale();
std::string pref_locale = prefs->GetString(prefs::kApplicationLocale); std::string pref_locale = prefs->GetString(prefs::kApplicationLocale);
if (!pref_locale.empty()) { if (pref_locale.empty())
if (prefs->GetString(prefs::kApplicationLocaleAccepted) == pref_locale) { pref_locale = prefs->GetString(prefs::kApplicationLocaleBackup);
// If locale is accepted then we do not want to show LocaleChange if (pref_locale.empty())
// notification. This notification is triggered by different values of pref_locale = g_browser_process->GetApplicationLocale();
// kApplicationLocaleBackup and kApplicationLocale preferences, DCHECK(!pref_locale.empty());
// so make them identical. profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
prefs->SetString(prefs::kApplicationLocaleBackup, pref_locale); LanguageSwitchMenu::SwitchLanguage(pref_locale);
} else {
std::string pref_locale_backup =
prefs->GetString(prefs::kApplicationLocaleBackup);
if (pref_locale_backup != cur_locale) {
if (pref_locale_backup == pref_locale || pref_locale_backup.empty()) {
prefs->SetString(prefs::kApplicationLocaleBackup, cur_locale);
}
}
}
LanguageSwitchMenu::SwitchLanguage(pref_locale);
return;
}
// 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.
std::string pref_locale_backup =
prefs->GetString(prefs::kApplicationLocaleBackup);
prefs->SetString(prefs::kApplicationLocaleBackup, cur_locale);
prefs->ScheduleSavePersistentPrefs();
if (!pref_locale_backup.empty()) {
prefs->SetString(prefs::kApplicationLocale, pref_locale_backup);
prefs->ScheduleSavePersistentPrefs();
LanguageSwitchMenu::SwitchLanguage(pref_locale_backup);
}
} }
void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) { void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) {
......
...@@ -383,7 +383,8 @@ void LanguageOptionsHandler::UiLanguageChangeCallback( ...@@ -383,7 +383,8 @@ void LanguageOptionsHandler::UiLanguageChangeCallback(
"LanguageOptions_UiLanguageChange_%s", language_code.c_str()); "LanguageOptions_UiLanguageChange_%s", language_code.c_str());
UserMetrics::RecordComputedAction(action); UserMetrics::RecordComputedAction(action);
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
dom_ui_->GetProfile()->ChangeApplicationLocale(language_code, false); dom_ui_->GetProfile()->ChangeAppLocale(
language_code, Profile::APP_LOCALE_CHANGED_VIA_SETTINGS);
#else #else
PrefService* pref_service = g_browser_process->local_state(); PrefService* pref_service = g_browser_process->local_state();
pref_service->SetString(prefs::kApplicationLocale, language_code); pref_service->SetString(prefs::kApplicationLocale, language_code);
......
...@@ -114,7 +114,6 @@ void Profile::RegisterUserPrefs(PrefService* prefs) { ...@@ -114,7 +114,6 @@ void Profile::RegisterUserPrefs(PrefService* prefs) {
// in user's profile for other platforms as well. // in user's profile for other platforms as well.
prefs->RegisterStringPref(prefs::kApplicationLocale, ""); prefs->RegisterStringPref(prefs::kApplicationLocale, "");
prefs->RegisterStringPref(prefs::kApplicationLocaleBackup, ""); prefs->RegisterStringPref(prefs::kApplicationLocaleBackup, "");
prefs->RegisterStringPref(prefs::kApplicationLocaleOverride, "");
prefs->RegisterStringPref(prefs::kApplicationLocaleAccepted, ""); prefs->RegisterStringPref(prefs::kApplicationLocaleAccepted, "");
#endif #endif
} }
...@@ -614,8 +613,7 @@ class OffTheRecordProfileImpl : public Profile, ...@@ -614,8 +613,7 @@ class OffTheRecordProfileImpl : public Profile,
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
virtual void ChangeApplicationLocale( virtual void ChangeAppLocale(const std::string& locale, AppLocaleChangedVia) {
const std::string& locale, bool keep_local) {
} }
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
......
...@@ -486,10 +486,20 @@ class Profile { ...@@ -486,10 +486,20 @@ class Profile {
virtual policy::ProfilePolicyContext* GetPolicyContext() = 0; virtual policy::ProfilePolicyContext* GetPolicyContext() = 0;
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// Changes application locale. enum AppLocaleChangedVia {
// "Keep local" means that changes should not be propagated to other devices. // Caused by chrome://settings change.
virtual void ChangeApplicationLocale( APP_LOCALE_CHANGED_VIA_SETTINGS,
const std::string& locale, bool keep_local) = 0; // Locale has been reverted via LocaleChangeGuard.
APP_LOCALE_CHANGED_VIA_REVERT,
// From login screen.
APP_LOCALE_CHANGED_VIA_LOGIN,
// Source unknown.
APP_LOCALE_CHANGED_VIA_UNKNOWN
};
// Changes application locale for a profile.
virtual void ChangeAppLocale(
const std::string& locale, AppLocaleChangedVia via) = 0;
// Returns ChromeOS's ProxyConfigServiceImpl, creating if not yet created. // Returns ChromeOS's ProxyConfigServiceImpl, creating if not yet created.
virtual chromeos::ProxyConfigServiceImpl* virtual chromeos::ProxyConfigServiceImpl*
......
...@@ -1372,28 +1372,75 @@ PromoCounter* ProfileImpl::GetInstantPromoCounter() { ...@@ -1372,28 +1372,75 @@ PromoCounter* ProfileImpl::GetInstantPromoCounter() {
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void ProfileImpl::ChangeApplicationLocale( void ProfileImpl::ChangeAppLocale(
const std::string& locale, bool keep_local) { const std::string& new_locale, AppLocaleChangedVia via) {
if (locale.empty()) { if (new_locale.empty()) {
NOTREACHED(); NOTREACHED();
return; return;
} }
if (keep_local) { std::string pref_locale = GetPrefs()->GetString(prefs::kApplicationLocale);
GetPrefs()->SetString(prefs::kApplicationLocaleOverride, locale); bool do_update_pref = true;
} else { switch (via) {
GetPrefs()->SetString(prefs::kApplicationLocale, locale); case APP_LOCALE_CHANGED_VIA_SETTINGS:
GetPrefs()->ClearPref(prefs::kApplicationLocaleOverride); 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 his personal locale preference.
// In case of APP_LOCALE_CHANGED_VIA_LOGIN we won't touch local state
// because login screen code is active and takes care of it.
g_browser_process->local_state()->SetString(
prefs::kApplicationLocale, new_locale);
break;
}
case APP_LOCALE_CHANGED_VIA_LOGIN: {
if (!pref_locale.empty()) {
DCHECK(pref_locale == new_locale);
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.
GetPrefs()->SetString(prefs::kApplicationLocaleBackup,
g_browser_process->GetApplicationLocale());
}
} 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 (!backup_locale.empty())
GetPrefs()->SetString(prefs::kApplicationLocale, backup_locale);
do_update_pref = false;
}
break;
}
case APP_LOCALE_CHANGED_VIA_UNKNOWN:
default: {
NOTREACHED();
break;
}
} }
GetPrefs()->SetString(prefs::kApplicationLocaleBackup, locale); if (do_update_pref)
GetPrefs()->ClearPref(prefs::kApplicationLocaleAccepted); GetPrefs()->SetString(prefs::kApplicationLocale, new_locale);
// We maintain kApplicationLocale property in both a global storage
// and user's profile. Global property determines locale of login screen, GetPrefs()->ScheduleSavePersistentPrefs();
// while user's profile determines his personal locale preference. g_browser_process->local_state()->ScheduleSavePersistentPrefs();
g_browser_process->local_state()->SetString(
prefs::kApplicationLocale, locale);
GetPrefs()->SavePersistentPrefs();
g_browser_process->local_state()->SavePersistentPrefs();
} }
chromeos::ProxyConfigServiceImpl* chromeos::ProxyConfigServiceImpl*
......
...@@ -130,8 +130,7 @@ class ProfileImpl : public Profile, ...@@ -130,8 +130,7 @@ class ProfileImpl : public Profile,
virtual policy::ProfilePolicyContext* GetPolicyContext(); virtual policy::ProfilePolicyContext* GetPolicyContext();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
virtual void ChangeApplicationLocale( virtual void ChangeAppLocale(const std::string& locale, AppLocaleChangedVia);
const std::string& locale, bool keep_local);
virtual chromeos::ProxyConfigServiceImpl* GetChromeOSProxyConfigServiceImpl(); virtual chromeos::ProxyConfigServiceImpl* GetChromeOSProxyConfigServiceImpl();
virtual void SetupChromeOSEnterpriseExtensionObserver(); virtual void SetupChromeOSEnterpriseExtensionObserver();
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
......
...@@ -32,8 +32,7 @@ PreferenceModelAssociator::PreferenceModelAssociator( ...@@ -32,8 +32,7 @@ PreferenceModelAssociator::PreferenceModelAssociator(
// synced_preferences set, taking care to filter out any preferences // synced_preferences set, taking care to filter out any preferences
// that are not registered. // that are not registered.
PrefService* pref_service = sync_service_->profile()->GetPrefs(); PrefService* pref_service = sync_service_->profile()->GetPrefs();
for (size_t i = 0; for (size_t i = 0; i < arraysize(kSynchronizedPreferences); ++i) {
i < static_cast<size_t>(arraysize(kSynchronizedPreferences)); ++i) {
if (pref_service->FindPreference(kSynchronizedPreferences[i])) if (pref_service->FindPreference(kSynchronizedPreferences[i]))
synced_preferences_.insert(kSynchronizedPreferences[i]); synced_preferences_.insert(kSynchronizedPreferences[i]);
} }
......
...@@ -46,16 +46,36 @@ const char kURLsToRestoreOnStartup[] = "session.urls_to_restore_on_startup"; ...@@ -46,16 +46,36 @@ const char kURLsToRestoreOnStartup[] = "session.urls_to_restore_on_startup";
// while user's profile determines his personal locale preference. // while user's profile determines his personal locale preference.
const char kApplicationLocale[] = "intl.app_locale"; const char kApplicationLocale[] = "intl.app_locale";
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// Non-syncable item. Used to detect locale change.
// Used for two-step initialization of locale in ChromeOS
// because synchronization of kApplicationLocale is not instant.
const char kApplicationLocaleBackup[] = "intl.app_locale_backup";
// Non-syncable item.
// Used to locally override synchronized kApplicationLocale preference.
const char kApplicationLocaleOverride[] = "intl.app_locale_override";
// Locale accepted by user. Non-syncable. // Locale accepted by user. Non-syncable.
// Used to determine whether we need to show Locale Change notification. // Used to determine whether we need to show Locale Change notification.
const char kApplicationLocaleAccepted[] = "intl.app_locale_accepted"; const char kApplicationLocaleAccepted[] = "intl.app_locale_accepted";
// Non-syncable item.
// It is used in two distinct ways.
// (1) Used for two-step initialization of locale in ChromeOS
// because synchronization of kApplicationLocale is not instant.
// (2) Used to detect locale change. Locale change is detected by
// LocaleChangeGuard in case values of kApplicationLocaleBackup and
// kApplicationLocale are both non-empty and differ.
// Following is a table showing how state of those prefs may change upon
// common real-life use cases:
// AppLocale Backup Accepted
// Initial login - A -
// Sync B A -
// Accept (B) B B B
// -----------------------------------------------------------
// Initial login - A -
// No sync and second login A A -
// Change options B B -
// -----------------------------------------------------------
// Initial login - A -
// Sync A A -
// Locale changed on login screen A C -
// Accept (A) A A A
// -----------------------------------------------------------
// Initial login - A -
// Sync B A -
// Revert A A -
const char kApplicationLocaleBackup[] = "intl.app_locale_backup";
#endif #endif
// The default character encoding to assume for a web page in the // The default character encoding to assume for a web page in the
......
...@@ -27,7 +27,6 @@ extern const char kURLsToRestoreOnStartup[]; ...@@ -27,7 +27,6 @@ extern const char kURLsToRestoreOnStartup[];
extern const char kApplicationLocale[]; extern const char kApplicationLocale[];
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
extern const char kApplicationLocaleBackup[]; extern const char kApplicationLocaleBackup[];
extern const char kApplicationLocaleOverride[];
extern const char kApplicationLocaleAccepted[]; extern const char kApplicationLocaleAccepted[];
#endif #endif
......
...@@ -298,7 +298,7 @@ class TestingProfile : public Profile { ...@@ -298,7 +298,7 @@ class TestingProfile : public Profile {
} }
virtual void SetupChromeOSEnterpriseExtensionObserver() { virtual void SetupChromeOSEnterpriseExtensionObserver() {
} }
virtual void ChangeApplicationLocale(const std::string&, bool) { virtual void ChangeAppLocale(const std::string&, AppLocaleChangedVia) {
} }
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment