• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/ui/webui/options/personal_options_handler.h"
6 
7 #include <string>
8 
9 #include "base/basictypes.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/path_service.h"
13 #include "base/stl_util-inl.h"
14 #include "base/stringprintf.h"
15 #include "base/time.h"
16 #include "base/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/sync/profile_sync_service.h"
22 #include "chrome/browser/sync/sync_setup_flow.h"
23 #include "chrome/browser/sync/sync_ui_util.h"
24 #include "chrome/browser/themes/theme_service.h"
25 #include "chrome/browser/themes/theme_service_factory.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/browser/ui/options/options_page_base.h"
28 #include "chrome/browser/ui/options/options_window.h"
29 #include "chrome/browser/ui/webui/options/options_managed_banner_handler.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/net/gaia/google_service_auth_error.h"
33 #include "chrome/common/url_constants.h"
34 #include "content/common/notification_service.h"
35 #include "grit/chromium_strings.h"
36 #include "grit/generated_resources.h"
37 #include "grit/locale_settings.h"
38 #include "grit/theme_resources.h"
39 #include "ui/base/l10n/l10n_util.h"
40 
41 #if defined(OS_CHROMEOS)
42 #include "chrome/browser/chromeos/login/user_manager.h"
43 #include "chrome/browser/chromeos/options/take_photo_dialog.h"
44 #include "chrome/browser/ui/browser_window.h"
45 #include "chrome/browser/ui/views/window.h"
46 #include "third_party/skia/include/core/SkBitmap.h"
47 #include "views/window/window.h"
48 #endif  // defined(OS_CHROMEOS)
49 #if defined(TOOLKIT_GTK)
50 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
51 #endif  // defined(TOOLKIT_GTK)
52 
PersonalOptionsHandler()53 PersonalOptionsHandler::PersonalOptionsHandler() {
54   const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
55   multiprofile_ = browser_command_line.HasSwitch(switches::kMultiProfiles);
56 #if defined(OS_CHROMEOS)
57   registrar_.Add(this,
58                  NotificationType::LOGIN_USER_IMAGE_CHANGED,
59                  NotificationService::AllSources());
60 #endif
61 }
62 
~PersonalOptionsHandler()63 PersonalOptionsHandler::~PersonalOptionsHandler() {
64   ProfileSyncService* sync_service =
65       web_ui_->GetProfile()->GetProfileSyncService();
66   if (sync_service)
67     sync_service->RemoveObserver(this);
68 }
69 
GetLocalizedValues(DictionaryValue * localized_strings)70 void PersonalOptionsHandler::GetLocalizedValues(
71     DictionaryValue* localized_strings) {
72   DCHECK(localized_strings);
73 
74   RegisterTitle(localized_strings, "personalPage",
75                 IDS_OPTIONS_CONTENT_TAB_LABEL);
76 
77 
78   localized_strings->SetString(
79       "syncOverview",
80       l10n_util::GetStringFUTF16(IDS_SYNC_OVERVIEW,
81                                  l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
82   localized_strings->SetString(
83       "syncFurtherOverview",
84       l10n_util::GetStringUTF16(IDS_SYNC_FURTHER_OVERVIEW));
85   localized_strings->SetString("syncSection",
86       multiprofile_ ?
87           l10n_util::GetStringUTF16(IDS_PROFILES_OPTIONS_GROUP_NAME) :
88           l10n_util::GetStringUTF16(IDS_SYNC_OPTIONS_GROUP_NAME));
89   localized_strings->SetString("customizeSync",
90       multiprofile_ ?
91           l10n_util::GetStringUTF16(IDS_PROFILES_SYNC_CUSTOMIZE_BUTTON_LABEL) :
92           l10n_util::GetStringUTF16(IDS_SYNC_CUSTOMIZE_BUTTON_LABEL));
93   if (multiprofile_) {
94     localized_strings->SetString("createNewProfile",
95         l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_INFO));
96     localized_strings->SetString("createProfileButton",
97         l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_BUTTON_LABEL));
98   }
99 
100   localized_strings->SetString("passwords",
101       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_GROUP_NAME));
102   localized_strings->SetString("passwordsAskToSave",
103       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_ASKTOSAVE));
104   localized_strings->SetString("passwordsNeverSave",
105       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_NEVERSAVE));
106   localized_strings->SetString("manage_passwords",
107       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS));
108 
109   localized_strings->SetString("autofill",
110       l10n_util::GetStringUTF16(IDS_AUTOFILL_SETTING_WINDOWS_GROUP_NAME));
111   localized_strings->SetString("autofillEnabled",
112       l10n_util::GetStringUTF16(IDS_OPTIONS_AUTOFILL_ENABLE));
113   localized_strings->SetString("manageAutofillSettings",
114       l10n_util::GetStringUTF16(IDS_OPTIONS_MANAGE_AUTOFILL_SETTINGS));
115 
116   localized_strings->SetString("browsingData",
117       l10n_util::GetStringUTF16(IDS_OPTIONS_BROWSING_DATA_GROUP_NAME));
118   localized_strings->SetString("importData",
119       l10n_util::GetStringUTF16(IDS_OPTIONS_IMPORT_DATA_BUTTON));
120 
121   localized_strings->SetString("themesGallery",
122       l10n_util::GetStringUTF16(IDS_THEMES_GALLERY_BUTTON));
123   localized_strings->SetString("themesGalleryURL",
124       l10n_util::GetStringUTF16(IDS_THEMES_GALLERY_URL));
125 
126 #if defined(TOOLKIT_GTK)
127   localized_strings->SetString("appearance",
128       l10n_util::GetStringUTF16(IDS_APPEARANCE_GROUP_NAME));
129   localized_strings->SetString("themesGTKButton",
130       l10n_util::GetStringUTF16(IDS_THEMES_GTK_BUTTON));
131   localized_strings->SetString("themesSetClassic",
132       l10n_util::GetStringUTF16(IDS_THEMES_SET_CLASSIC));
133   localized_strings->SetString("showWindowDecorations",
134       l10n_util::GetStringUTF16(IDS_SHOW_WINDOW_DECORATIONS_RADIO));
135   localized_strings->SetString("hideWindowDecorations",
136       l10n_util::GetStringUTF16(IDS_HIDE_WINDOW_DECORATIONS_RADIO));
137 #else
138   localized_strings->SetString("themes",
139       l10n_util::GetStringUTF16(IDS_THEMES_GROUP_NAME));
140   localized_strings->SetString("themesReset",
141       l10n_util::GetStringUTF16(IDS_THEMES_RESET_BUTTON));
142 #endif
143 
144   // Sync select control.
145   ListValue* sync_select_list = new ListValue;
146   ListValue* datatypes = new ListValue;
147   datatypes->Append(Value::CreateBooleanValue(false));
148   datatypes->Append(
149       Value::CreateStringValue(
150           l10n_util::GetStringUTF8(IDS_SYNC_OPTIONS_SELECT_DATATYPES)));
151   sync_select_list->Append(datatypes);
152   ListValue* everything = new ListValue;
153   everything->Append(Value::CreateBooleanValue(true));
154   everything->Append(
155       Value::CreateStringValue(
156           l10n_util::GetStringUTF8(IDS_SYNC_OPTIONS_SELECT_EVERYTHING)));
157   sync_select_list->Append(everything);
158   localized_strings->Set("syncSelectList", sync_select_list);
159 
160   // Sync page.
161   localized_strings->SetString("syncPage",
162       l10n_util::GetStringUTF16(IDS_SYNC_NTP_SYNC_SECTION_TITLE));
163   localized_strings->SetString("sync_title",
164       l10n_util::GetStringUTF16(IDS_CUSTOMIZE_SYNC_DESCRIPTION));
165   localized_strings->SetString("syncsettings",
166       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_PREFERENCES));
167   localized_strings->SetString("syncbookmarks",
168       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_BOOKMARKS));
169   localized_strings->SetString("synctypedurls",
170       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_TYPED_URLS));
171   localized_strings->SetString("syncpasswords",
172       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_PASSWORDS));
173   localized_strings->SetString("syncextensions",
174       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_EXTENSIONS));
175   localized_strings->SetString("syncautofill",
176       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_AUTOFILL));
177   localized_strings->SetString("syncthemes",
178       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_THEMES));
179   localized_strings->SetString("syncapps",
180       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_APPS));
181   localized_strings->SetString("syncsessions",
182       l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_SESSIONS));
183 
184 #if defined(OS_CHROMEOS)
185   localized_strings->SetString("account",
186       l10n_util::GetStringUTF16(IDS_OPTIONS_PERSONAL_ACCOUNT_GROUP_NAME));
187   localized_strings->SetString("enableScreenlock",
188       l10n_util::GetStringUTF16(IDS_OPTIONS_ENABLE_SCREENLOCKER_CHECKBOX));
189   localized_strings->SetString("changePicture",
190       l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE));
191 #endif
192 }
193 
RegisterMessages()194 void PersonalOptionsHandler::RegisterMessages() {
195   DCHECK(web_ui_);
196   web_ui_->RegisterMessageCallback(
197       "showSyncActionDialog",
198       NewCallback(this, &PersonalOptionsHandler::ShowSyncActionDialog));
199   web_ui_->RegisterMessageCallback(
200       "showSyncLoginDialog",
201       NewCallback(this, &PersonalOptionsHandler::ShowSyncLoginDialog));
202   web_ui_->RegisterMessageCallback(
203       "showCustomizeSyncDialog",
204       NewCallback(this, &PersonalOptionsHandler::ShowCustomizeSyncDialog));
205   web_ui_->RegisterMessageCallback(
206       "themesReset",
207       NewCallback(this, &PersonalOptionsHandler::ThemesReset));
208 #if defined(TOOLKIT_GTK)
209   web_ui_->RegisterMessageCallback(
210       "themesSetGTK",
211       NewCallback(this, &PersonalOptionsHandler::ThemesSetGTK));
212 #endif
213   web_ui_->RegisterMessageCallback("updatePreferredDataTypes",
214       NewCallback(this, &PersonalOptionsHandler::OnPreferredDataTypesUpdated));
215 #if defined(OS_CHROMEOS)
216   web_ui_->RegisterMessageCallback(
217       "loadAccountPicture",
218       NewCallback(this, &PersonalOptionsHandler::LoadAccountPicture));
219 #endif
220 }
221 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)222 void PersonalOptionsHandler::Observe(NotificationType type,
223                                      const NotificationSource& source,
224                                      const NotificationDetails& details) {
225   if (type == NotificationType::BROWSER_THEME_CHANGED) {
226     ObserveThemeChanged();
227 #if defined(OS_CHROMEOS)
228   } else if (type == NotificationType::LOGIN_USER_IMAGE_CHANGED) {
229     LoadAccountPicture(NULL);
230 #endif
231   } else {
232     OptionsPageUIHandler::Observe(type, source, details);
233   }
234 }
235 
OnStateChanged()236 void PersonalOptionsHandler::OnStateChanged() {
237   string16 status_label;
238   string16 link_label;
239   ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService();
240   DCHECK(service);
241   bool managed = service->IsManaged();
242   bool sync_setup_completed = service->HasSyncSetupCompleted();
243   bool status_has_error = sync_ui_util::GetStatusLabels(service,
244       &status_label, &link_label) == sync_ui_util::SYNC_ERROR;
245 
246   string16 start_stop_button_label;
247   bool is_start_stop_button_visible = false;
248   bool is_start_stop_button_enabled = false;
249   if (sync_setup_completed) {
250     start_stop_button_label = multiprofile_ ?
251         l10n_util::GetStringUTF16(IDS_PROFILES_DISCONNECT_BUTTON_LABEL) :
252         l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_BUTTON_LABEL);
253 #if defined(OS_CHROMEOS)
254     is_start_stop_button_visible = false;
255 #else
256     is_start_stop_button_visible = true;
257 #endif  // defined(OS_CHROMEOS)
258     is_start_stop_button_enabled = !managed;
259   } else if (service->SetupInProgress()) {
260     start_stop_button_label =
261         l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS);
262     is_start_stop_button_visible = true;
263     is_start_stop_button_enabled = false;
264   } else {
265     start_stop_button_label =
266         multiprofile_ ?
267             l10n_util::GetStringUTF16(IDS_PROFILES_CONNECT_BUTTON_LABEL) :
268             l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL);
269     is_start_stop_button_visible = true;
270     is_start_stop_button_enabled = !managed;
271   }
272 
273   scoped_ptr<Value> completed(Value::CreateBooleanValue(sync_setup_completed));
274   web_ui_->CallJavascriptFunction("PersonalOptions.setSyncSetupCompleted",
275                                   *completed);
276 
277   scoped_ptr<Value> label(Value::CreateStringValue(status_label));
278   web_ui_->CallJavascriptFunction("PersonalOptions.setSyncStatus", *label);
279 
280   scoped_ptr<Value> enabled(
281       Value::CreateBooleanValue(is_start_stop_button_enabled));
282   web_ui_->CallJavascriptFunction("PersonalOptions.setStartStopButtonEnabled",
283                                   *enabled);
284 
285   scoped_ptr<Value> visible(
286       Value::CreateBooleanValue(is_start_stop_button_visible));
287   web_ui_->CallJavascriptFunction("PersonalOptions.setStartStopButtonVisible",
288                                   *visible);
289 
290   label.reset(Value::CreateStringValue(start_stop_button_label));
291   web_ui_->CallJavascriptFunction("PersonalOptions.setStartStopButtonLabel",
292                                   *label);
293 
294   label.reset(Value::CreateStringValue(link_label));
295   web_ui_->CallJavascriptFunction("PersonalOptions.setSyncActionLinkLabel",
296                                   *label);
297 
298   enabled.reset(Value::CreateBooleanValue(!managed));
299   web_ui_->CallJavascriptFunction("PersonalOptions.setSyncActionLinkEnabled",
300                                   *enabled);
301 
302   visible.reset(Value::CreateBooleanValue(status_has_error));
303   web_ui_->CallJavascriptFunction("PersonalOptions.setSyncStatusErrorVisible",
304                                   *visible);
305 
306   // Set profile creation text and button if multi-profiles switch is on.
307   if (multiprofile_) {
308     visible.reset(Value::CreateBooleanValue(true));
309     web_ui_->CallJavascriptFunction("PersonalOptions.setProfilesSectionVisible",
310                                     *visible);
311 
312     // TODO(mirandac): enable when back end is ready.
313     enabled.reset(Value::CreateBooleanValue(false));
314     web_ui_->CallJavascriptFunction(
315         "PersonalOptions.setNewProfileButtonEnabled", *enabled);
316   } else {
317     visible.reset(Value::CreateBooleanValue(false));
318     web_ui_->CallJavascriptFunction("PersonalOptions.setProfilesSectionVisible",
319                                     *visible);
320   }
321 }
322 
OnLoginSuccess()323 void PersonalOptionsHandler::OnLoginSuccess() {
324   OnStateChanged();
325 }
326 
OnLoginFailure(const GoogleServiceAuthError & error)327 void PersonalOptionsHandler::OnLoginFailure(
328     const GoogleServiceAuthError& error) {
329   OnStateChanged();
330 }
331 
ObserveThemeChanged()332 void PersonalOptionsHandler::ObserveThemeChanged() {
333   Profile* profile = web_ui_->GetProfile();
334 #if defined(TOOLKIT_GTK)
335   GtkThemeService* provider = GtkThemeService::GetFrom(profile);
336   bool is_gtk_theme = provider->UseGtkTheme();
337   FundamentalValue gtk_enabled(!is_gtk_theme);
338   web_ui_->CallJavascriptFunction(
339       "options.PersonalOptions.setGtkThemeButtonEnabled", gtk_enabled);
340 #else
341   ThemeService* provider = ThemeServiceFactory::GetForProfile(profile);
342   bool is_gtk_theme = false;
343 #endif
344 
345   bool is_classic_theme = !is_gtk_theme && provider->UsingDefaultTheme();
346   FundamentalValue enabled(!is_classic_theme);
347   web_ui_->CallJavascriptFunction(
348       "options.PersonalOptions.setThemesResetButtonEnabled", enabled);
349 }
350 
Initialize()351 void PersonalOptionsHandler::Initialize() {
352   banner_handler_.reset(
353       new OptionsManagedBannerHandler(web_ui_,
354                                       ASCIIToUTF16("PersonalOptions"),
355                                       OPTIONS_PAGE_CONTENT));
356 
357   // Listen for theme installation.
358   registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
359                  NotificationService::AllSources());
360   ObserveThemeChanged();
361 
362   ProfileSyncService* sync_service =
363       web_ui_->GetProfile()->GetProfileSyncService();
364   if (sync_service) {
365     sync_service->AddObserver(this);
366     OnStateChanged();
367 
368     DictionaryValue args;
369     SyncSetupFlow::GetArgsForConfigure(sync_service, &args);
370 
371     web_ui_->CallJavascriptFunction("PersonalOptions.setRegisteredDataTypes",
372                                     args);
373   } else {
374     web_ui_->CallJavascriptFunction("options.PersonalOptions.hideSyncSection");
375   }
376 }
377 
ShowSyncActionDialog(const ListValue * args)378 void PersonalOptionsHandler::ShowSyncActionDialog(const ListValue* args) {
379   ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService();
380   DCHECK(service);
381   service->ShowErrorUI(NULL);
382 }
383 
ShowSyncLoginDialog(const ListValue * args)384 void PersonalOptionsHandler::ShowSyncLoginDialog(const ListValue* args) {
385   ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService();
386   DCHECK(service);
387   service->ShowLoginDialog(NULL);
388   ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_OPTIONS);
389 }
390 
ShowCustomizeSyncDialog(const ListValue * args)391 void PersonalOptionsHandler::ShowCustomizeSyncDialog(const ListValue* args) {
392   ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService();
393   DCHECK(service);
394   service->ShowConfigure(NULL, false);
395 }
396 
ThemesReset(const ListValue * args)397 void PersonalOptionsHandler::ThemesReset(const ListValue* args) {
398   UserMetricsRecordAction(UserMetricsAction("Options_ThemesReset"));
399   ThemeServiceFactory::GetForProfile(web_ui_->GetProfile())->UseDefaultTheme();
400 }
401 
402 #if defined(TOOLKIT_GTK)
ThemesSetGTK(const ListValue * args)403 void PersonalOptionsHandler::ThemesSetGTK(const ListValue* args) {
404   UserMetricsRecordAction(UserMetricsAction("Options_GtkThemeSet"));
405   ThemeServiceFactory::GetForProfile(web_ui_->GetProfile())->SetNativeTheme();
406 }
407 #endif
408 
OnPreferredDataTypesUpdated(const ListValue * args)409 void PersonalOptionsHandler::OnPreferredDataTypesUpdated(
410     const ListValue* args) {
411   NotificationService::current()->Notify(
412       NotificationType::SYNC_DATA_TYPES_UPDATED,
413       Source<Profile>(web_ui_->GetProfile()),
414       NotificationService::NoDetails());
415 }
416 
417 #if defined(OS_CHROMEOS)
LoadAccountPicture(const ListValue * args)418 void PersonalOptionsHandler::LoadAccountPicture(const ListValue* args) {
419   const chromeos::UserManager::User& user =
420       chromeos::UserManager::Get()->logged_in_user();
421   std::string email = user.email();
422   if (!email.empty()) {
423     // int64 is either long or long long, but we need a certain format
424     // specifier.
425     long long timestamp = base::TimeTicks::Now().ToInternalValue();
426     StringValue image_url(
427         StringPrintf("%s%s?id=%lld",
428                      chrome::kChromeUIUserImageURL,
429                      email.c_str(),
430                      timestamp));
431     web_ui_->CallJavascriptFunction("PersonalOptions.setAccountPicture",
432                                     image_url);
433   }
434 }
435 
436 #endif
437