1 // Copyright (c) 2012 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 "ash/system/tray/system_tray.h"
9 #include "ash/system/tray/system_tray_notifier.h"
10 #include "base/bind.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chromeos/settings/device_settings_service.h"
15 #include "chrome/browser/notifications/notification_delegate.h"
16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_commands.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/host_desktop.h"
22 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/pref_names.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/user_metrics.h"
27 #include "content/public/browser/web_contents.h"
28 #include "grit/generated_resources.h"
29 #include "grit/theme_resources.h"
30 #include "ui/base/l10n/l10n_util.h"
32 using content::UserMetricsAction
;
33 using content::WebContents
;
37 class LocaleChangeGuard::Delegate
: public NotificationDelegate
{
39 explicit Delegate(chromeos::LocaleChangeGuard
* master
) : master_(master
) {}
40 virtual void Close(bool by_user
) OVERRIDE
;
41 virtual void Display() OVERRIDE
{}
42 virtual void Error() OVERRIDE
{}
43 virtual void Click() OVERRIDE
{}
44 virtual std::string
id() const OVERRIDE
;
45 virtual content::RenderViewHost
* GetRenderViewHost() const OVERRIDE
{
50 virtual ~Delegate() {}
53 chromeos::LocaleChangeGuard
* master_
;
55 DISALLOW_COPY_AND_ASSIGN(Delegate
);
58 LocaleChangeGuard::LocaleChangeGuard(Profile
* profile
)
62 registrar_
.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
63 content::NotificationService::AllSources());
66 LocaleChangeGuard::~LocaleChangeGuard() {}
68 void LocaleChangeGuard::OnLogin() {
69 registrar_
.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
70 content::NotificationService::AllBrowserContextsAndSources());
73 void LocaleChangeGuard::RevertLocaleChange() {
74 if (profile_
== NULL
||
75 from_locale_
.empty() ||
83 content::RecordAction(UserMetricsAction("LanguageChange_Revert"));
84 profile_
->ChangeAppLocale(
85 from_locale_
, Profile::APP_LOCALE_CHANGED_VIA_REVERT
);
87 Browser
* browser
= browser::FindTabbedBrowser(profile_
, false,
88 chrome::HOST_DESKTOP_TYPE_ASH
);
90 chrome::ExecuteCommand(browser
, IDC_EXIT
);
93 void LocaleChangeGuard::RevertLocaleChangeCallback(const ListValue
* list
) {
97 void LocaleChangeGuard::Observe(int type
,
98 const content::NotificationSource
& source
,
99 const content::NotificationDetails
& details
) {
100 if (profile_
== NULL
) {
105 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
: {
107 content::Source
<WebContents
>(source
)->GetBrowserContext()) {
108 // We need to perform locale change check only once, so unsubscribe.
109 registrar_
.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
110 content::NotificationService::AllSources());
115 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
: {
116 if (DeviceSettingsService::Get()->HasPrivateOwnerKey()) {
117 PrefService
* local_state
= g_browser_process
->local_state();
119 PrefService
* prefs
= profile_
->GetPrefs();
124 std::string owner_locale
=
125 prefs
->GetString(prefs::kApplicationLocale
);
126 if (!owner_locale
.empty())
127 local_state
->SetString(prefs::kOwnerLocale
, owner_locale
);
139 void LocaleChangeGuard::Check() {
140 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
141 if (cur_locale
.empty()) {
146 PrefService
* prefs
= profile_
->GetPrefs();
152 std::string to_locale
= prefs
->GetString(prefs::kApplicationLocale
);
153 if (to_locale
!= cur_locale
) {
154 // This conditional branch can occur in cases like:
155 // (1) kApplicationLocale preference was modified by synchronization;
156 // (2) kApplicationLocale is managed by policy.
160 std::string from_locale
= prefs
->GetString(prefs::kApplicationLocaleBackup
);
161 if (from_locale
.empty() || from_locale
== to_locale
)
162 return; // No locale change was detected, just exit.
164 if (prefs
->GetString(prefs::kApplicationLocaleAccepted
) == to_locale
)
165 return; // Already accepted.
167 // Locale change detected, showing notification.
168 if (from_locale_
!= from_locale
|| to_locale_
!= to_locale
) {
169 // Falling back to showing message in current locale.
171 "Showing locale change notification in current (not previous) language";
172 PrepareChangingLocale(from_locale
, to_locale
);
175 ash::Shell::GetInstance()->system_tray_notifier()->NotifyLocaleChanged(
176 this, cur_locale
, from_locale_
, to_locale_
);
179 void LocaleChangeGuard::AcceptLocaleChange() {
180 if (profile_
== NULL
||
181 from_locale_
.empty() ||
182 to_locale_
.empty()) {
187 // Check whether locale has been reverted or changed.
188 // If not: mark current locale as accepted.
191 PrefService
* prefs
= profile_
->GetPrefs();
196 if (prefs
->GetString(prefs::kApplicationLocale
) != to_locale_
)
198 content::RecordAction(UserMetricsAction("LanguageChange_Accept"));
199 prefs
->SetString(prefs::kApplicationLocaleBackup
, to_locale_
);
200 prefs
->SetString(prefs::kApplicationLocaleAccepted
, to_locale_
);
203 void LocaleChangeGuard::PrepareChangingLocale(
204 const std::string
& from_locale
, const std::string
& to_locale
) {
205 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
206 if (!from_locale
.empty())
207 from_locale_
= from_locale
;
208 if (!to_locale
.empty())
209 to_locale_
= to_locale
;
211 if (!from_locale_
.empty() && !to_locale_
.empty()) {
212 string16 from
= l10n_util::GetDisplayNameForLocale(
213 from_locale_
, cur_locale
, true);
214 string16 to
= l10n_util::GetDisplayNameForLocale(
215 to_locale_
, cur_locale
, true);
217 title_text_
= l10n_util::GetStringUTF16(
218 IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE
);
219 message_text_
= l10n_util::GetStringFUTF16(
220 IDS_LOCALE_CHANGE_MESSAGE
, from
, to
);
221 revert_link_text_
= l10n_util::GetStringFUTF16(
222 IDS_LOCALE_CHANGE_REVERT_MESSAGE
, from
);
226 void LocaleChangeGuard::Delegate::Close(bool by_user
) {
228 master_
->AcceptLocaleChange();
231 std::string
LocaleChangeGuard::Delegate::id() const {
232 // Arbitrary unique Id.
233 return "8c386938-1e3f-11e0-ac7b-18a90520e2e5";
236 } // namespace chromeos