1 // Copyright 2013 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/ui/ash/system_tray_delegate_chromeos.h"
12 #include "ash/ash_switches.h"
13 #include "ash/desktop_background/desktop_background_controller.h"
14 #include "ash/metrics/user_metrics_recorder.h"
15 #include "ash/session_state_delegate.h"
16 #include "ash/session_state_observer.h"
17 #include "ash/shell.h"
18 #include "ash/shell_delegate.h"
19 #include "ash/shell_window_ids.h"
20 #include "ash/system/bluetooth/bluetooth_observer.h"
21 #include "ash/system/date/clock_observer.h"
22 #include "ash/system/drive/drive_observer.h"
23 #include "ash/system/ime/ime_observer.h"
24 #include "ash/system/logout_button/logout_button_observer.h"
25 #include "ash/system/tray/system_tray.h"
26 #include "ash/system/tray/system_tray_delegate.h"
27 #include "ash/system/tray/system_tray_notifier.h"
28 #include "ash/system/tray_accessibility.h"
29 #include "ash/system/tray_caps_lock.h"
30 #include "ash/system/user/login_status.h"
31 #include "ash/system/user/update_observer.h"
32 #include "ash/system/user/user_observer.h"
33 #include "ash/volume_control_delegate.h"
34 #include "ash/wm/lock_state_controller.h"
35 #include "base/bind_helpers.h"
36 #include "base/callback.h"
37 #include "base/command_line.h"
38 #include "base/logging.h"
39 #include "base/memory/weak_ptr.h"
40 #include "base/prefs/pref_service.h"
41 #include "base/strings/stringprintf.h"
42 #include "base/strings/utf_string_conversions.h"
43 #include "base/sys_info.h"
44 #include "base/time/time.h"
45 #include "chrome/browser/browser_process.h"
46 #include "chrome/browser/chrome_notification_types.h"
47 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
48 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
49 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h"
50 #include "chrome/browser/chromeos/charger_replace/charger_replacement_dialog.h"
51 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h"
52 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
53 #include "chrome/browser/chromeos/drive/job_list.h"
54 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
55 #include "chrome/browser/chromeos/events/system_key_event_listener.h"
56 #include "chrome/browser/chromeos/input_method/input_method_util.h"
57 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
58 #include "chrome/browser/chromeos/login/help_app_launcher.h"
59 #include "chrome/browser/chromeos/login/login_display_host.h"
60 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
61 #include "chrome/browser/chromeos/login/login_wizard.h"
62 #include "chrome/browser/chromeos/login/startup_utils.h"
63 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
64 #include "chrome/browser/chromeos/login/user.h"
65 #include "chrome/browser/chromeos/login/user_adding_screen.h"
66 #include "chrome/browser/chromeos/login/user_manager.h"
67 #include "chrome/browser/chromeos/options/network_config_view.h"
68 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
69 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
70 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
71 #include "chrome/browser/chromeos/settings/cros_settings.h"
72 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
73 #include "chrome/browser/drive/drive_service_interface.h"
74 #include "chrome/browser/feedback/tracing_manager.h"
75 #include "chrome/browser/google/google_util.h"
76 #include "chrome/browser/lifetime/application_lifetime.h"
77 #include "chrome/browser/profiles/profile_manager.h"
78 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
79 #include "chrome/browser/ui/ash/volume_controller_chromeos.h"
80 #include "chrome/browser/ui/browser.h"
81 #include "chrome/browser/ui/browser_finder.h"
82 #include "chrome/browser/ui/chrome_pages.h"
83 #include "chrome/browser/ui/host_desktop.h"
84 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
85 #include "chrome/browser/ui/singleton_tabs.h"
86 #include "chrome/browser/ui/tabs/tab_strip_model.h"
87 #include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h"
88 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
89 #include "chrome/browser/upgrade_detector.h"
90 #include "chrome/common/pref_names.h"
91 #include "chrome/common/url_constants.h"
92 #include "chromeos/chromeos_switches.h"
93 #include "chromeos/dbus/dbus_thread_manager.h"
94 #include "chromeos/dbus/session_manager_client.h"
95 #include "chromeos/ime/extension_ime_util.h"
96 #include "chromeos/ime/input_method_manager.h"
97 #include "chromeos/ime/xkeyboard.h"
98 #include "chromeos/login/login_state.h"
99 #include "components/policy/core/common/cloud/cloud_policy_store.h"
100 #include "content/public/browser/notification_observer.h"
101 #include "content/public/browser/notification_service.h"
102 #include "content/public/browser/user_metrics.h"
103 #include "content/public/browser/web_contents.h"
104 #include "device/bluetooth/bluetooth_adapter.h"
105 #include "device/bluetooth/bluetooth_adapter_factory.h"
106 #include "device/bluetooth/bluetooth_device.h"
107 #include "grit/ash_strings.h"
108 #include "grit/generated_resources.h"
109 #include "grit/locale_settings.h"
110 #include "net/base/escape.h"
111 #include "third_party/cros_system_api/dbus/service_constants.h"
112 #include "ui/base/l10n/l10n_util.h"
113 #include "ui/base/l10n/time_format.h"
115 using drive::DriveIntegrationService;
116 using drive::DriveIntegrationServiceFactory;
122 // The minimum session length limit that can be set.
123 const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
125 // The maximum session length limit that can be set.
126 const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
128 const char kDisplaySettingsSubPageName[] = "display";
129 const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan";
131 // The URL for the Google Drive settings page.
132 const char kDriveSettingsPageURL[] = "https://drive.google.com";
134 void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
135 const input_method::InputMethodUtil& util,
136 ash::IMEInfo* info) {
138 info->name = util.GetInputMethodLongName(ime);
139 info->medium_name = util.GetInputMethodMediumName(ime);
140 info->short_name = util.GetInputMethodShortName(ime);
141 info->third_party = extension_ime_util::IsExtensionIME(ime.id());
144 gfx::NativeWindow GetNativeWindowByStatus(ash::user::LoginStatus login_status,
145 bool session_started) {
147 (!session_started || login_status == ash::user::LOGGED_IN_NONE ||
148 login_status == ash::user::LOGGED_IN_LOCKED) ?
149 ash::internal::kShellWindowId_LockSystemModalContainer :
150 ash::internal::kShellWindowId_SystemModalContainer;
151 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
155 // Converts drive::JobInfo to ash::DriveOperationStatus.
156 // If the job is not of type that ash tray is interested, returns false.
157 bool ConvertToDriveOperationStatus(const drive::JobInfo& info,
158 ash::DriveOperationStatus* status) {
159 if (info.job_type == drive::TYPE_DOWNLOAD_FILE) {
160 status->type = ash::DriveOperationStatus::OPERATION_DOWNLOAD;
161 } else if (info.job_type == drive::TYPE_UPLOAD_NEW_FILE ||
162 info.job_type == drive::TYPE_UPLOAD_EXISTING_FILE) {
163 status->type = ash::DriveOperationStatus::OPERATION_UPLOAD;
168 if (info.state == drive::STATE_NONE)
169 status->state = ash::DriveOperationStatus::OPERATION_NOT_STARTED;
171 status->state = ash::DriveOperationStatus::OPERATION_IN_PROGRESS;
173 status->id = info.job_id;
174 status->file_path = info.file_path;
175 status->progress = info.num_total_bytes == 0 ? 0.0 :
176 static_cast<double>(info.num_completed_bytes) /
177 static_cast<double>(info.num_total_bytes);
181 // Converts drive::JobInfo that has finished in |error| state
182 // to ash::DriveOperationStatus.
183 // If the job is not of type that ash tray is interested, returns false.
184 bool ConvertToFinishedDriveOperationStatus(const drive::JobInfo& info,
185 drive::FileError error,
186 ash::DriveOperationStatus* status) {
187 if (!ConvertToDriveOperationStatus(info, status))
189 status->state = (error == drive::FILE_ERROR_OK)
190 ? ash::DriveOperationStatus::OPERATION_COMPLETED
191 : ash::DriveOperationStatus::OPERATION_FAILED;
195 // Converts a list of drive::JobInfo to a list of ash::DriveOperationStatusList.
196 ash::DriveOperationStatusList ConvertToDriveStatusList(
197 const std::vector<drive::JobInfo>& list) {
198 ash::DriveOperationStatusList results;
199 for (size_t i = 0; i < list.size(); ++i) {
200 ash::DriveOperationStatus status;
201 if (ConvertToDriveOperationStatus(list[i], &status))
202 results.push_back(status);
207 void BluetoothPowerFailure() {
208 // TODO(sad): Show an error bubble?
211 void BluetoothSetDiscoveringError() {
212 LOG(ERROR) << "BluetoothSetDiscovering failed.";
215 void BluetoothDeviceConnectError(
216 device::BluetoothDevice::ConnectErrorCode error_code) {
217 // TODO(sad): Do something?
220 // Shows the settings sub page in the last active browser. If there is no such
221 // browser, creates a new browser with the settings sub page.
222 void ShowSettingsSubPageForAppropriateBrowser(const std::string& sub_page,
224 chrome::ScopedTabbedBrowserDisplayer displayer(profile,
225 chrome::HOST_DESKTOP_TYPE_ASH);
226 chrome::ShowSettingsSubPage(displayer.browser(), sub_page);
229 void ShowNetworkSettingsPage(const std::string& service_path) {
230 std::string page = chrome::kInternetOptionsSubPage;
231 page += "?servicePath=" + net::EscapeUrlEncodedData(service_path, true);
232 content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog"));
233 ShowSettingsSubPageForAppropriateBrowser(
234 page, ProfileManager::GetPrimaryUserProfile());
237 void OnAcceptMultiprofilesIntro(bool no_show_again) {
238 PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
239 prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again);
240 UserAddingScreen::Get()->Start();
245 SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
246 : weak_ptr_factory_(this),
248 clock_type_(base::GetHourClockType()),
249 search_key_mapped_to_(input_method::kSearchKey),
250 screen_locked_(false),
251 have_session_start_time_(false),
252 have_session_length_limit_(false),
253 volume_control_delegate_(new VolumeController()),
254 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
255 kSystemUse24HourClock,
256 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
257 base::Unretained(this)))) {
258 // Register notifications on construction so that events such as
259 // PROFILE_CREATED do not get missed if they happen before Initialize().
260 registrar_.reset(new content::NotificationRegistrar);
261 registrar_->Add(this,
262 chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
263 content::NotificationService::AllSources());
264 registrar_->Add(this,
265 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
266 content::NotificationService::AllSources());
267 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) {
268 registrar_->Add(this,
269 chrome::NOTIFICATION_SESSION_STARTED,
270 content::NotificationService::AllSources());
272 registrar_->Add(this,
273 chrome::NOTIFICATION_PROFILE_CREATED,
274 content::NotificationService::AllSources());
275 registrar_->Add(this,
276 chrome::NOTIFICATION_PROFILE_DESTROYED,
277 content::NotificationService::AllSources());
280 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
281 content::NotificationService::AllSources());
284 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
285 content::NotificationService::AllSources());
288 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
289 content::NotificationService::AllSources());
292 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
293 content::NotificationService::AllSources());
296 void SystemTrayDelegateChromeOS::Initialize() {
297 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
299 input_method::InputMethodManager::Get()->AddObserver(this);
302 if (SystemKeyEventListener::GetInstance())
303 SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this);
305 device::BluetoothAdapterFactory::GetAdapter(
306 base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady,
307 weak_ptr_factory_.GetWeakPtr()));
309 ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(
312 if (LoginState::IsInitialized())
313 LoginState::Get()->AddObserver(this);
316 void SystemTrayDelegateChromeOS::Shutdown() {
317 device_settings_observer_.reset();
320 void SystemTrayDelegateChromeOS::InitializeOnAdapterReady(
321 scoped_refptr<device::BluetoothAdapter> adapter) {
322 bluetooth_adapter_ = adapter;
323 CHECK(bluetooth_adapter_.get());
324 bluetooth_adapter_->AddObserver(this);
326 local_state_registrar_.reset(new PrefChangeRegistrar);
327 local_state_registrar_->Init(g_browser_process->local_state());
329 UpdateSessionStartTime();
330 UpdateSessionLengthLimit();
332 local_state_registrar_->Add(
333 prefs::kSessionStartTime,
334 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime,
335 base::Unretained(this)));
336 local_state_registrar_->Add(
337 prefs::kSessionLengthLimit,
338 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit,
339 base::Unretained(this)));
341 policy::BrowserPolicyConnectorChromeOS* policy_connector =
342 g_browser_process->platform_part()->browser_policy_connector_chromeos();
343 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
344 policy_connector->GetDeviceCloudPolicyManager();
346 policy_manager->core()->store()->AddObserver(this);
347 UpdateEnterpriseDomain();
350 SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() {
351 // Unregister PrefChangeRegistrars.
352 local_state_registrar_.reset();
353 user_pref_registrar_.reset();
355 // Unregister content notifications befure destroying any components.
358 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
359 input_method::InputMethodManager::Get()->RemoveObserver(this);
360 if (SystemKeyEventListener::GetInstance())
361 SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this);
362 bluetooth_adapter_->RemoveObserver(this);
363 ash::Shell::GetInstance()
364 ->session_state_delegate()
365 ->RemoveSessionStateObserver(this);
366 LoginState::Get()->RemoveObserver(this);
368 // Stop observing Drive operations.
369 UnobserveDriveUpdates();
371 policy::BrowserPolicyConnectorChromeOS* connector =
372 g_browser_process->platform_part()->browser_policy_connector_chromeos();
373 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
374 connector->GetDeviceCloudPolicyManager();
376 policy_manager->core()->store()->RemoveObserver(this);
379 // Overridden from ash::SystemTrayDelegate:
380 bool SystemTrayDelegateChromeOS::GetTrayVisibilityOnStartup() {
381 // In case of OOBE / sign in screen tray will be shown later.
382 return LoginState::Get()->IsUserLoggedIn();
385 ash::user::LoginStatus SystemTrayDelegateChromeOS::GetUserLoginStatus() const {
386 // All non-logged in ChromeOS specific LOGGED_IN states map to the same
387 // Ash specific LOGGED_IN state.
388 if (!LoginState::Get()->IsUserLoggedIn())
389 return ash::user::LOGGED_IN_NONE;
392 return ash::user::LOGGED_IN_LOCKED;
394 LoginState::LoggedInUserType user_type =
395 LoginState::Get()->GetLoggedInUserType();
397 case LoginState::LOGGED_IN_USER_NONE:
398 return ash::user::LOGGED_IN_NONE;
399 case LoginState::LOGGED_IN_USER_REGULAR:
400 return ash::user::LOGGED_IN_USER;
401 case LoginState::LOGGED_IN_USER_OWNER:
402 return ash::user::LOGGED_IN_OWNER;
403 case LoginState::LOGGED_IN_USER_GUEST:
404 return ash::user::LOGGED_IN_GUEST;
405 case LoginState::LOGGED_IN_USER_RETAIL_MODE:
406 return ash::user::LOGGED_IN_RETAIL_MODE;
407 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
408 return ash::user::LOGGED_IN_PUBLIC;
409 case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED:
410 return ash::user::LOGGED_IN_LOCALLY_MANAGED;
411 case LoginState::LOGGED_IN_USER_KIOSK_APP:
412 return ash::user::LOGGED_IN_KIOSK_APP;
415 return ash::user::LOGGED_IN_NONE;
418 bool SystemTrayDelegateChromeOS::IsOobeCompleted() const {
419 if (!base::SysInfo::IsRunningOnChromeOS() &&
420 LoginState::Get()->IsUserLoggedIn())
422 return StartupUtils::IsOobeCompleted();
425 void SystemTrayDelegateChromeOS::ChangeProfilePicture() {
426 content::RecordAction(
427 base::UserMetricsAction("OpenChangeProfilePictureDialog"));
428 ShowSettingsSubPageForAppropriateBrowser(
429 chrome::kChangeProfilePictureSubPage,
430 ProfileManager::GetActiveUserProfile());
433 const std::string SystemTrayDelegateChromeOS::GetEnterpriseDomain() const {
434 return enterprise_domain_;
437 const base::string16 SystemTrayDelegateChromeOS::GetEnterpriseMessage() const {
438 if (GetEnterpriseDomain().empty())
439 return base::string16();
440 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE,
441 base::UTF8ToUTF16(GetEnterpriseDomain()));
444 const std::string SystemTrayDelegateChromeOS::GetLocallyManagedUserManager()
446 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
447 return std::string();
448 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayEmail(
449 chromeos::UserManager::Get()->GetActiveUser()->email());
453 SystemTrayDelegateChromeOS::GetLocallyManagedUserManagerName() const {
454 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
455 return base::string16();
456 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayName(
457 chromeos::UserManager::Get()->GetActiveUser()->email());
460 const base::string16 SystemTrayDelegateChromeOS::GetLocallyManagedUserMessage()
462 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
463 return base::string16();
464 return l10n_util::GetStringFUTF16(
465 IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE,
466 base::UTF8ToUTF16(GetLocallyManagedUserManager()));
469 bool SystemTrayDelegateChromeOS::SystemShouldUpgrade() const {
470 return UpgradeDetector::GetInstance()->notify_upgrade();
473 base::HourClockType SystemTrayDelegateChromeOS::GetHourClockType() const {
477 void SystemTrayDelegateChromeOS::ShowSettings() {
478 chrome::ScopedTabbedBrowserDisplayer displayer(
479 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
480 chrome::ShowSettings(displayer.browser());
483 bool SystemTrayDelegateChromeOS::ShouldShowSettings() {
484 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings();
487 void SystemTrayDelegateChromeOS::ShowDateSettings() {
488 content::RecordAction(base::UserMetricsAction("ShowDateOptions"));
489 std::string sub_page =
490 std::string(chrome::kSearchSubPage) + "#" +
491 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
492 // Everybody can change the time zone (even though it is a device setting).
493 ShowSettingsSubPageForAppropriateBrowser(
494 sub_page, ProfileManager::GetActiveUserProfile());
497 void SystemTrayDelegateChromeOS::ShowNetworkSettings(
498 const std::string& service_path) {
499 if (!LoginState::Get()->IsUserLoggedIn())
501 ShowNetworkSettingsPage(service_path);
504 void SystemTrayDelegateChromeOS::ShowBluetoothSettings() {
505 // TODO(sad): Make this work.
508 void SystemTrayDelegateChromeOS::ShowDisplaySettings() {
509 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions"));
510 ShowSettingsSubPageForAppropriateBrowser(
511 kDisplaySettingsSubPageName, ProfileManager::GetActiveUserProfile());
514 void SystemTrayDelegateChromeOS::ShowChromeSlow() {
515 chrome::ScopedTabbedBrowserDisplayer displayer(
516 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
517 chrome::ShowSlow(displayer.browser());
520 bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() {
521 // Packaged app is not counted as 'last active', so if a browser opening the
522 // display settings is in background of a packaged app, it will return true.
523 // TODO(mukai): fix this.
524 Browser* active_browser =
525 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH);
529 content::WebContents* active_contents =
530 active_browser->tab_strip_model()->GetActiveWebContents();
531 if (!active_contents)
534 GURL visible_url = active_contents->GetLastCommittedURL();
535 std::string display_settings_url =
536 std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName;
537 std::string display_overscan_url = std::string(chrome::kChromeUISettingsURL) +
538 kDisplayOverscanSettingsSubPageName;
539 return (visible_url.spec() != display_settings_url) &&
540 (visible_url.spec() != display_overscan_url);
543 void SystemTrayDelegateChromeOS::ShowDriveSettings() {
544 // TODO(tengs): Open the drive-specific settings page once we put it in.
545 // For now just show Google Drive main page.
546 chrome::ScopedTabbedBrowserDisplayer displayer(
547 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
548 chrome::ShowSingletonTabOverwritingNTP(
550 chrome::GetSingletonTabNavigateParams(displayer.browser(),
551 GURL(kDriveSettingsPageURL)));
554 void SystemTrayDelegateChromeOS::ShowIMESettings() {
555 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog"));
556 ShowSettingsSubPageForAppropriateBrowser(
557 chrome::kLanguageOptionsSubPage, ProfileManager::GetActiveUserProfile());
560 void SystemTrayDelegateChromeOS::ShowHelp() {
561 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(),
562 chrome::HOST_DESKTOP_TYPE_ASH,
563 chrome::HELP_SOURCE_MENU);
566 void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() {
567 chrome::ScopedTabbedBrowserDisplayer displayer(
568 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
569 accessibility::ShowAccessibilityHelp(displayer.browser());
572 void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() {
573 content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings"));
574 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
575 l10n_util::GetStringUTF8(
576 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY);
577 ShowSettingsSubPageForAppropriateBrowser(
578 sub_page, ProfileManager::GetActiveUserProfile());
581 void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() {
582 chrome::ScopedTabbedBrowserDisplayer displayer(
583 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
584 chrome::ShowPolicy(displayer.browser());
587 void SystemTrayDelegateChromeOS::ShowLocallyManagedUserInfo() {
588 // TODO(antrim): find out what should we show in this case.
589 // http://crbug.com/229762
592 void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() {
593 ash::user::LoginStatus status = GetUserLoginStatus();
594 if (status == ash::user::LOGGED_IN_NONE ||
595 status == ash::user::LOGGED_IN_LOCKED) {
596 scoped_refptr<chromeos::HelpAppLauncher> help_app(
597 new chromeos::HelpAppLauncher(GetNativeWindow()));
598 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE);
600 GURL url(google_util::StringAppendGoogleLocaleParam(
601 chrome::kLearnMoreEnterpriseURL));
602 chrome::ScopedTabbedBrowserDisplayer displayer(
603 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
604 chrome::ShowSingletonTab(displayer.browser(), url);
608 void SystemTrayDelegateChromeOS::ShowUserLogin() {
609 ash::Shell* shell = ash::Shell::GetInstance();
610 if (!shell->delegate()->IsMultiProfilesEnabled())
613 // Only regular users could add other users to current session.
614 if (UserManager::Get()->GetActiveUser()->GetType() !=
615 User::USER_TYPE_REGULAR) {
619 if (static_cast<int>(UserManager::Get()->GetLoggedInUsers().size()) >=
620 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers())
623 // Launch sign in screen to add another user to current session.
624 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) {
625 // Don't show dialog if any logged in user in multi-profiles session
627 bool show_intro = true;
628 const UserList logged_in_users = UserManager::Get()->GetLoggedInUsers();
629 for (UserList::const_iterator it = logged_in_users.begin();
630 it != logged_in_users.end();
632 show_intro &= !multi_user_util::GetProfileFromUserID(
633 multi_user_util::GetUserIDFromEmail((*it)->email()))
635 ->GetBoolean(prefs::kMultiProfileNeverShowIntro);
640 base::Callback<void(bool)> on_accept =
641 base::Bind(&OnAcceptMultiprofilesIntro);
642 ShowMultiprofilesIntroDialog(on_accept);
644 UserAddingScreen::Get()->Start();
649 bool SystemTrayDelegateChromeOS::ShowSpringChargerReplacementDialog() {
650 if (!ChargerReplacementDialog::ShouldShowDialog())
653 ChargerReplacementDialog* dialog =
654 new ChargerReplacementDialog(GetNativeWindow());
659 bool SystemTrayDelegateChromeOS::IsSpringChargerReplacementDialogVisible() {
660 return ChargerReplacementDialog::IsDialogVisible();
663 bool SystemTrayDelegateChromeOS::HasUserConfirmedSafeSpringCharger() {
664 return ChargerReplacementHandler::GetChargerStatusPref() ==
665 ChargerReplacementHandler::CONFIRM_SAFE_CHARGER;
668 void SystemTrayDelegateChromeOS::ShutDown() {
669 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
672 void SystemTrayDelegateChromeOS::SignOut() {
673 chrome::AttemptUserExit();
676 void SystemTrayDelegateChromeOS::RequestLockScreen() {
677 // TODO(antrim) : additional logging for crbug/173178
678 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate";
679 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
682 void SystemTrayDelegateChromeOS::RequestRestartForUpdate() {
683 // We expect that UpdateEngine is in "Reboot for update" state now.
684 chrome::NotifyAndTerminate(true /* fast path */);
687 void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices(
688 ash::BluetoothDeviceList* list) {
689 device::BluetoothAdapter::DeviceList devices =
690 bluetooth_adapter_->GetDevices();
691 for (size_t i = 0; i < devices.size(); ++i) {
692 device::BluetoothDevice* device = devices[i];
693 ash::BluetoothDeviceInfo info;
694 info.address = device->GetAddress();
695 info.display_name = device->GetName();
696 info.connected = device->IsConnected();
697 info.connecting = device->IsConnecting();
698 info.paired = device->IsPaired();
699 list->push_back(info);
703 void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() {
704 bluetooth_adapter_->StartDiscovering(
705 base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError));
708 void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() {
709 bluetooth_adapter_->StopDiscovering(
710 base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError));
713 void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice(
714 const std::string& address) {
715 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
716 if (!device || device->IsConnecting() ||
717 (device->IsConnected() && device->IsPaired())) {
720 if (device->IsPaired() && !device->IsConnectable())
722 if (device->IsPaired() || !device->IsPairable()) {
723 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
724 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE);
725 device->Connect(NULL,
726 base::Bind(&base::DoNothing),
727 base::Bind(&BluetoothDeviceConnectError));
728 } else { // Show paring dialog for the unpaired device.
729 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
730 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE);
731 BluetoothPairingDialog* dialog =
732 new BluetoothPairingDialog(GetNativeWindow(), device);
733 // The dialog deletes itself on close.
738 bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() {
739 return bluetooth_adapter_->IsDiscovering();
742 void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) {
743 input_method::InputMethodManager* manager =
744 input_method::InputMethodManager::Get();
745 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
746 input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod();
747 ExtractIMEInfo(ime, *util, info);
748 info->selected = true;
751 void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) {
752 input_method::InputMethodManager* manager =
753 input_method::InputMethodManager::Get();
754 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
755 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors(
756 manager->GetActiveInputMethods());
757 std::string current = manager->GetCurrentInputMethod().id();
758 for (size_t i = 0; i < ime_descriptors->size(); i++) {
759 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i);
761 ExtractIMEInfo(ime, *util, &info);
762 info.selected = ime.id() == current;
763 list->push_back(info);
767 void SystemTrayDelegateChromeOS::GetCurrentIMEProperties(
768 ash::IMEPropertyInfoList* list) {
769 input_method::InputMethodManager* manager =
770 input_method::InputMethodManager::Get();
771 input_method::InputMethodPropertyList properties =
772 manager->GetCurrentInputMethodProperties();
773 for (size_t i = 0; i < properties.size(); ++i) {
774 ash::IMEPropertyInfo property;
775 property.key = properties[i].key;
776 property.name = base::UTF8ToUTF16(properties[i].label);
777 property.selected = properties[i].is_selection_item_checked;
778 list->push_back(property);
782 void SystemTrayDelegateChromeOS::SwitchIME(const std::string& ime_id) {
783 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id);
786 void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string& key) {
787 input_method::InputMethodManager::Get()->ActivateInputMethodProperty(key);
790 void SystemTrayDelegateChromeOS::CancelDriveOperation(int32 operation_id) {
791 DriveIntegrationService* integration_service = FindDriveIntegrationService();
792 if (!integration_service)
795 integration_service->job_list()->CancelJob(operation_id);
798 void SystemTrayDelegateChromeOS::GetDriveOperationStatusList(
799 ash::DriveOperationStatusList* list) {
800 DriveIntegrationService* integration_service = FindDriveIntegrationService();
801 if (!integration_service)
804 *list = ConvertToDriveStatusList(
805 integration_service->job_list()->GetJobInfoList());
808 void SystemTrayDelegateChromeOS::ShowNetworkConfigure(
809 const std::string& network_id,
810 gfx::NativeWindow parent_window) {
811 NetworkConfigView::Show(network_id, parent_window);
814 bool SystemTrayDelegateChromeOS::EnrollNetwork(
815 const std::string& network_id,
816 gfx::NativeWindow parent_window) {
817 return enrollment::CreateDialog(network_id, parent_window);
820 void SystemTrayDelegateChromeOS::ManageBluetoothDevices() {
821 content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage"));
822 std::string sub_page =
823 std::string(chrome::kSearchSubPage) + "#" +
824 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH);
825 ShowSettingsSubPageForAppropriateBrowser(
826 sub_page, ProfileManager::GetPrimaryUserProfile());
829 void SystemTrayDelegateChromeOS::ToggleBluetooth() {
830 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(),
831 base::Bind(&base::DoNothing),
832 base::Bind(&BluetoothPowerFailure));
835 void SystemTrayDelegateChromeOS::ShowMobileSimDialog() {
836 SimDialogDelegate::ShowDialog(GetNativeWindow(),
837 SimDialogDelegate::SIM_DIALOG_UNLOCK);
840 void SystemTrayDelegateChromeOS::ShowMobileSetupDialog(
841 const std::string& service_path) {
842 MobileSetupDialog::Show(service_path);
845 void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog(
846 const std::string& type) {
847 if (type == shill::kTypeCellular) {
848 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
851 NetworkConfigView::ShowForType(type, GetNativeWindow());
854 bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() {
855 return bluetooth_adapter_->IsPresent();
858 bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() {
859 return bluetooth_adapter_->IsPowered();
862 void SystemTrayDelegateChromeOS::ChangeProxySettings() {
863 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE);
864 LoginDisplayHostImpl::default_host()->OpenProxySettings();
867 ash::VolumeControlDelegate*
868 SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const {
869 return volume_control_delegate_.get();
872 void SystemTrayDelegateChromeOS::SetVolumeControlDelegate(
873 scoped_ptr<ash::VolumeControlDelegate> delegate) {
874 volume_control_delegate_.swap(delegate);
877 bool SystemTrayDelegateChromeOS::GetSessionStartTime(
878 base::TimeTicks* session_start_time) {
879 *session_start_time = session_start_time_;
880 return have_session_start_time_;
883 bool SystemTrayDelegateChromeOS::GetSessionLengthLimit(
884 base::TimeDelta* session_length_limit) {
885 *session_length_limit = session_length_limit_;
886 return have_session_length_limit_;
889 int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() {
890 return l10n_util::GetLocalizedContentsWidthInPixels(
891 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS);
894 void SystemTrayDelegateChromeOS::ActiveUserWasChanged() {
895 GetSystemTrayNotifier()->NotifyUserUpdate();
898 ash::SystemTray* SystemTrayDelegateChromeOS::GetPrimarySystemTray() {
899 return ash::Shell::GetInstance()->GetPrimarySystemTray();
902 ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() {
903 return ash::Shell::GetInstance()->system_tray_notifier();
906 void SystemTrayDelegateChromeOS::SetProfile(Profile* profile) {
907 // Stop observing the current |user_profile_| on Drive integration status.
908 UnobserveDriveUpdates();
910 user_profile_ = profile;
912 // Restart observation, now for the newly set |profile|.
913 ObserveDriveUpdates();
915 PrefService* prefs = profile->GetPrefs();
916 user_pref_registrar_.reset(new PrefChangeRegistrar);
917 user_pref_registrar_->Init(prefs);
918 user_pref_registrar_->Add(
919 prefs::kUse24HourClock,
920 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
921 base::Unretained(this)));
922 user_pref_registrar_->Add(
923 prefs::kLanguageRemapSearchKeyTo,
924 base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged,
925 base::Unretained(this)));
926 user_pref_registrar_->Add(
927 prefs::kShowLogoutButtonInTray,
928 base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray,
929 base::Unretained(this)));
930 user_pref_registrar_->Add(
931 prefs::kLogoutDialogDurationMs,
932 base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration,
933 base::Unretained(this)));
934 user_pref_registrar_->Add(
935 prefs::kLargeCursorEnabled,
936 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
937 base::Unretained(this),
938 ash::A11Y_NOTIFICATION_NONE));
939 user_pref_registrar_->Add(
940 prefs::kAutoclickEnabled,
941 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
942 base::Unretained(this),
943 ash::A11Y_NOTIFICATION_NONE));
944 user_pref_registrar_->Add(
945 prefs::kShouldAlwaysShowAccessibilityMenu,
946 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
947 base::Unretained(this),
948 ash::A11Y_NOTIFICATION_NONE));
949 user_pref_registrar_->Add(
950 prefs::kPerformanceTracingEnabled,
951 base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing,
952 base::Unretained(this)));
955 UpdateShowLogoutButtonInTray();
956 UpdateLogoutDialogDuration();
957 UpdatePerformanceTracing();
958 search_key_mapped_to_ =
959 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo);
962 bool SystemTrayDelegateChromeOS::UnsetProfile(Profile* profile) {
963 if (profile != user_profile_)
965 user_pref_registrar_.reset();
969 void SystemTrayDelegateChromeOS::ObserveDriveUpdates() {
970 DriveIntegrationService* integration_service = FindDriveIntegrationService();
971 if (integration_service)
972 integration_service->job_list()->AddObserver(this);
975 void SystemTrayDelegateChromeOS::UnobserveDriveUpdates() {
976 DriveIntegrationService* integration_service = FindDriveIntegrationService();
977 if (integration_service)
978 integration_service->job_list()->RemoveObserver(this);
981 bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const {
982 return ShouldUse24HourClock();
985 bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const {
986 // On login screen and in guest mode owner default is used for
987 // kUse24HourClock preference.
988 const ash::user::LoginStatus status = GetUserLoginStatus();
989 const CrosSettings* const cros_settings = CrosSettings::Get();
990 bool system_use_24_hour_clock = true;
991 const bool system_value_found = cros_settings->GetBoolean(
992 kSystemUse24HourClock, &system_use_24_hour_clock);
994 if ((status == ash::user::LOGGED_IN_NONE) || !user_pref_registrar_)
995 return (system_value_found
996 ? system_use_24_hour_clock
997 : (base::GetHourClockType() == base::k24HourClock));
999 const PrefService::Preference* user_pref =
1000 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock);
1001 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue())
1002 return (system_value_found
1003 ? system_use_24_hour_clock
1004 : (base::GetHourClockType() == base::k24HourClock));
1006 bool use_24_hour_clock = true;
1007 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock);
1008 return use_24_hour_clock;
1011 void SystemTrayDelegateChromeOS::UpdateClockType() {
1012 const bool use_24_hour_clock = ShouldUse24HourClock();
1013 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock;
1014 GetSystemTrayNotifier()->NotifyDateFormatChanged();
1015 // This also works for enterprise-managed devices because they never have
1017 if (chromeos::UserManager::Get()->IsCurrentUserOwner())
1018 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
1021 void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() {
1022 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
1023 user_pref_registrar_->prefs()->GetBoolean(
1024 prefs::kShowLogoutButtonInTray));
1027 void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() {
1028 const int duration_ms =
1029 user_pref_registrar_->prefs()->GetInteger(prefs::kLogoutDialogDurationMs);
1030 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged(
1031 base::TimeDelta::FromMilliseconds(duration_ms));
1034 void SystemTrayDelegateChromeOS::UpdateSessionStartTime() {
1035 const PrefService* local_state = local_state_registrar_->prefs();
1036 if (local_state->HasPrefPath(prefs::kSessionStartTime)) {
1037 have_session_start_time_ = true;
1038 session_start_time_ = base::TimeTicks::FromInternalValue(
1039 local_state->GetInt64(prefs::kSessionStartTime));
1041 have_session_start_time_ = false;
1042 session_start_time_ = base::TimeTicks();
1044 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
1047 void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() {
1048 const PrefService* local_state = local_state_registrar_->prefs();
1049 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) {
1050 have_session_length_limit_ = true;
1051 session_length_limit_ = base::TimeDelta::FromMilliseconds(
1052 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit),
1053 kSessionLengthLimitMinMs),
1054 kSessionLengthLimitMaxMs));
1056 have_session_length_limit_ = false;
1057 session_length_limit_ = base::TimeDelta();
1059 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
1062 // LoginState::Observer overrides.
1063 void SystemTrayDelegateChromeOS::LoggedInStateChanged() {
1064 // It apparently sometimes takes a while after login before the current user
1065 // is recognized as the owner. Make sure that the system-wide clock setting
1066 // is updated when the recognition eventually happens
1067 // (http://crbug.com/278601).
1069 // Note that it isn't safe to blindly call UpdateClockType() from this
1070 // method, as LoggedInStateChanged() is also called before the logged-in
1071 // user's profile has actually been loaded (http://crbug.com/317745). The
1072 // system tray's time format is updated at login via SetProfile().
1073 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) {
1074 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock,
1075 ShouldUse24HourClock());
1079 // Overridden from SessionManagerClient::Observer.
1080 void SystemTrayDelegateChromeOS::ScreenIsLocked() {
1081 screen_locked_ = true;
1082 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1085 void SystemTrayDelegateChromeOS::ScreenIsUnlocked() {
1086 screen_locked_ = false;
1087 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1090 gfx::NativeWindow SystemTrayDelegateChromeOS::GetNativeWindow() const {
1091 bool session_started = ash::Shell::GetInstance()
1092 ->session_state_delegate()
1093 ->IsActiveUserSessionStarted();
1094 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started);
1097 // content::NotificationObserver implementation.
1098 void SystemTrayDelegateChromeOS::Observe(
1100 const content::NotificationSource& source,
1101 const content::NotificationDetails& details) {
1103 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
1104 UpgradeDetector* detector =
1105 content::Source<UpgradeDetector>(source).ptr();
1106 ash::UpdateObserver::UpdateSeverity severity =
1107 ash::UpdateObserver::UPDATE_NORMAL;
1108 switch (detector->upgrade_notification_stage()) {
1109 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
1110 severity = ash::UpdateObserver::UPDATE_SEVERE_RED;
1113 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
1114 severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE;
1117 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
1118 severity = ash::UpdateObserver::UPDATE_LOW_GREEN;
1121 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
1123 severity = ash::UpdateObserver::UPDATE_NORMAL;
1126 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity);
1129 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
1130 // This notification is also sent on login screen when user avatar
1131 // is loaded from file.
1132 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) {
1133 GetSystemTrayNotifier()->NotifyUserUpdate();
1137 case chrome::NOTIFICATION_PROFILE_CREATED: {
1138 SetProfile(content::Source<Profile>(source).ptr());
1139 registrar_->Remove(this,
1140 chrome::NOTIFICATION_PROFILE_CREATED,
1141 content::NotificationService::AllSources());
1144 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1145 if (UnsetProfile(content::Source<Profile>(source).ptr())) {
1146 registrar_->Remove(this,
1147 chrome::NOTIFICATION_PROFILE_DESTROYED,
1148 content::NotificationService::AllSources());
1152 case chrome::NOTIFICATION_SESSION_STARTED: {
1153 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1154 GetUserLoginStatus());
1155 SetProfile(ProfileManager::GetActiveUserProfile());
1158 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK:
1159 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE:
1160 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER:
1161 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD: {
1162 AccessibilityStatusEventDetails* accessibility_status =
1163 content::Details<AccessibilityStatusEventDetails>(details).ptr();
1164 OnAccessibilityModeChanged(accessibility_status->notify);
1172 void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() {
1173 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger(
1174 prefs::kLanguageRemapSearchKeyTo);
1177 void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged(
1178 ash::AccessibilityNotificationVisibility notify) {
1179 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify);
1182 void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() {
1183 if (!user_pref_registrar_)
1185 bool value = user_pref_registrar_->prefs()->GetBoolean(
1186 prefs::kPerformanceTracingEnabled);
1187 GetSystemTrayNotifier()->NotifyTracingModeChanged(value);
1190 // Overridden from InputMethodManager::Observer.
1191 void SystemTrayDelegateChromeOS::InputMethodChanged(
1192 input_method::InputMethodManager* manager,
1193 bool show_message) {
1194 // |show_message| in ash means the message_center notifications
1195 // which should not be shown unless kDisableIMEModeIndicator is
1196 // on, since the mode indicator already notifies the user.
1197 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1198 switches::kDisableIMEModeIndicator)) {
1199 show_message = false;
1201 GetSystemTrayNotifier()->NotifyRefreshIME(show_message);
1204 void SystemTrayDelegateChromeOS::InputMethodPropertyChanged(
1205 input_method::InputMethodManager* manager) {
1206 GetSystemTrayNotifier()->NotifyRefreshIME(false);
1209 // drive::JobListObserver overrides.
1210 void SystemTrayDelegateChromeOS::OnJobAdded(const drive::JobInfo& job_info) {
1211 OnJobUpdated(job_info);
1214 void SystemTrayDelegateChromeOS::OnJobDone(const drive::JobInfo& job_info,
1215 drive::FileError error) {
1216 ash::DriveOperationStatus status;
1217 if (ConvertToFinishedDriveOperationStatus(job_info, error, &status))
1218 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status);
1221 void SystemTrayDelegateChromeOS::OnJobUpdated(const drive::JobInfo& job_info) {
1222 ash::DriveOperationStatus status;
1223 if (ConvertToDriveOperationStatus(job_info, &status))
1224 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status);
1227 DriveIntegrationService*
1228 SystemTrayDelegateChromeOS::FindDriveIntegrationService() {
1229 return user_profile_
1230 ? DriveIntegrationServiceFactory::FindForProfile(user_profile_)
1234 // Overridden from BluetoothAdapter::Observer.
1235 void SystemTrayDelegateChromeOS::AdapterPresentChanged(
1236 device::BluetoothAdapter* adapter,
1238 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1241 void SystemTrayDelegateChromeOS::AdapterPoweredChanged(
1242 device::BluetoothAdapter* adapter,
1244 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1247 void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged(
1248 device::BluetoothAdapter* adapter,
1250 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1253 void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter* adapter,
1254 device::BluetoothDevice* device) {
1255 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1258 void SystemTrayDelegateChromeOS::DeviceChanged(
1259 device::BluetoothAdapter* adapter,
1260 device::BluetoothDevice* device) {
1261 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1264 void SystemTrayDelegateChromeOS::DeviceRemoved(
1265 device::BluetoothAdapter* adapter,
1266 device::BluetoothDevice* device) {
1267 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1270 // Overridden from SystemKeyEventListener::CapsLockObserver.
1271 void SystemTrayDelegateChromeOS::OnCapsLockChange(bool enabled) {
1272 bool search_mapped_to_caps_lock = false;
1273 if (!base::SysInfo::IsRunningOnChromeOS() ||
1274 search_key_mapped_to_ == input_method::kCapsLockKey)
1275 search_mapped_to_caps_lock = true;
1276 GetSystemTrayNotifier()->NotifyCapsLockChanged(enabled,
1277 search_mapped_to_caps_lock);
1280 void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() {
1281 policy::BrowserPolicyConnectorChromeOS* connector =
1282 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1283 std::string enterprise_domain = connector->GetEnterpriseDomain();
1284 if (enterprise_domain_ != enterprise_domain) {
1285 enterprise_domain_ = enterprise_domain;
1286 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1290 // Overridden from CloudPolicyStore::Observer
1291 void SystemTrayDelegateChromeOS::OnStoreLoaded(
1292 policy::CloudPolicyStore* store) {
1293 UpdateEnterpriseDomain();
1296 void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore* store) {
1297 UpdateEnterpriseDomain();
1300 // Overridden from ash::SessionStateObserver
1301 void SystemTrayDelegateChromeOS::UserAddedToSession(
1302 const std::string& user_id) {
1303 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1306 ash::SystemTrayDelegate* CreateSystemTrayDelegate() {
1307 return new SystemTrayDelegateChromeOS();
1310 } // namespace chromeos