1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/locale_change_guard.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chromeos/login/user_manager.h"
12 #include "chrome/browser/notifications/notification_delegate.h"
13 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/pref_names.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h"
20 #include "content/public/browser/user_metrics.h"
21 #include "content/public/browser/web_contents.h"
22 #include "grit/generated_resources.h"
23 #include "grit/theme_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
26 using content::UserMetricsAction
;
27 using content::WebContents
;
31 class LocaleChangeGuard::Delegate
: public NotificationDelegate
{
33 explicit Delegate(chromeos::LocaleChangeGuard
* master
) : master_(master
) {}
34 void Close(bool by_user
);
38 std::string
id() const;
41 chromeos::LocaleChangeGuard
* master_
;
43 DISALLOW_COPY_AND_ASSIGN(Delegate
);
46 LocaleChangeGuard::LocaleChangeGuard(Profile
* profile
)
51 registrar_
.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED
,
52 content::NotificationService::AllSources());
55 LocaleChangeGuard::~LocaleChangeGuard() {}
57 void LocaleChangeGuard::OnLogin() {
58 registrar_
.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
59 content::NotificationService::AllBrowserContextsAndSources());
62 void LocaleChangeGuard::RevertLocaleChange(const ListValue
* list
) {
65 from_locale_
.empty() ||
73 content::RecordAction(UserMetricsAction("LanguageChange_Revert"));
74 profile_
->ChangeAppLocale(
75 from_locale_
, Profile::APP_LOCALE_CHANGED_VIA_REVERT
);
77 Browser
* browser
= Browser::GetTabbedBrowser(profile_
, false);
79 browser
->ExecuteCommand(IDC_EXIT
);
82 void LocaleChangeGuard::Observe(int type
,
83 const content::NotificationSource
& source
,
84 const content::NotificationDetails
& details
) {
85 if (profile_
== NULL
) {
90 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
: {
92 content::Source
<WebContents
>(source
)->GetBrowserContext()) {
93 // We need to perform locale change check only once, so unsubscribe.
94 registrar_
.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
95 content::NotificationService::AllSources());
100 case chrome::NOTIFICATION_OWNERSHIP_CHECKED
: {
101 if (UserManager::Get()->current_user_is_owner()) {
102 PrefService
* local_state
= g_browser_process
->local_state();
104 PrefService
* prefs
= profile_
->GetPrefs();
109 std::string owner_locale
=
110 prefs
->GetString(prefs::kApplicationLocale
);
111 if (!owner_locale
.empty())
112 local_state
->SetString(prefs::kOwnerLocale
, owner_locale
);
124 void LocaleChangeGuard::Check() {
126 // Somehow we are invoked more than once. Once is enough.
130 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
131 if (cur_locale
.empty()) {
136 PrefService
* prefs
= profile_
->GetPrefs();
142 std::string to_locale
= prefs
->GetString(prefs::kApplicationLocale
);
143 if (to_locale
!= cur_locale
) {
144 // This conditional branch can occur in cases like:
145 // (1) kApplicationLocale preference was modified by synchronization;
146 // (2) kApplicationLocale is managed by policy.
150 std::string from_locale
= prefs
->GetString(prefs::kApplicationLocaleBackup
);
151 if (from_locale
.empty() || from_locale
== to_locale
)
152 return; // No locale change was detected, just exit.
154 if (prefs
->GetString(prefs::kApplicationLocaleAccepted
) == to_locale
)
155 return; // Already accepted.
157 // Locale change detected, showing notification.
158 if (from_locale_
!= from_locale
|| to_locale_
!= to_locale
) {
159 // Falling back to showing message in current locale.
161 "Showing locale change notification in current (not previous) language";
162 PrepareChangingLocale(from_locale
, to_locale
);
164 note_
.reset(new chromeos::SystemNotification(
167 IDR_NOTIFICATION_LOCALE_CHANGE
,
170 message_text_
, revert_link_text_
,
171 base::Bind(&LocaleChangeGuard::RevertLocaleChange
,
174 false); // non-sticky
177 void LocaleChangeGuard::AcceptLocaleChange() {
180 from_locale_
.empty() ||
181 to_locale_
.empty()) {
186 // Check whether locale has been reverted or changed.
187 // If not: mark current locale as accepted.
190 PrefService
* prefs
= profile_
->GetPrefs();
195 if (prefs
->GetString(prefs::kApplicationLocale
) != to_locale_
)
197 content::RecordAction(UserMetricsAction("LanguageChange_Accept"));
198 prefs
->SetString(prefs::kApplicationLocaleBackup
, to_locale_
);
199 prefs
->SetString(prefs::kApplicationLocaleAccepted
, to_locale_
);
202 void LocaleChangeGuard::PrepareChangingLocale(
203 const std::string
& from_locale
, const std::string
& to_locale
) {
204 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
205 if (!from_locale
.empty())
206 from_locale_
= from_locale
;
207 if (!to_locale
.empty())
208 to_locale_
= to_locale
;
210 if (!from_locale_
.empty() && !to_locale_
.empty()) {
211 string16 from
= l10n_util::GetDisplayNameForLocale(
212 from_locale_
, cur_locale
, true);
213 string16 to
= l10n_util::GetDisplayNameForLocale(
214 to_locale_
, cur_locale
, true);
216 title_text_
= l10n_util::GetStringUTF16(
217 IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE
);
218 message_text_
= l10n_util::GetStringFUTF16(
219 IDS_LOCALE_CHANGE_MESSAGE
, from
, to
);
220 revert_link_text_
= l10n_util::GetStringFUTF16(
221 IDS_LOCALE_CHANGE_REVERT_MESSAGE
, from
);
225 void LocaleChangeGuard::Delegate::Close(bool by_user
) {
227 master_
->AcceptLocaleChange();
230 std::string
LocaleChangeGuard::Delegate::id() const {
231 // Arbitrary unique Id.
232 return "8c386938-1e3f-11e0-ac7b-18a90520e2e5";
235 } // namespace chromeos