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/input_method/input_method_util.h"
56 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
57 #include "chrome/browser/chromeos/login/help_app_launcher.h"
58 #include "chrome/browser/chromeos/login/login_display_host.h"
59 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
60 #include "chrome/browser/chromeos/login/login_wizard.h"
61 #include "chrome/browser/chromeos/login/startup_utils.h"
62 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
63 #include "chrome/browser/chromeos/login/user.h"
64 #include "chrome/browser/chromeos/login/user_adding_screen.h"
65 #include "chrome/browser/chromeos/login/user_manager.h"
66 #include "chrome/browser/chromeos/options/network_config_view.h"
67 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
68 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
69 #include "chrome/browser/chromeos/settings/cros_settings.h"
70 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
71 #include "chrome/browser/chromeos/system_key_event_listener.h"
72 #include "chrome/browser/drive/drive_service_interface.h"
73 #include "chrome/browser/feedback/tracing_manager.h"
74 #include "chrome/browser/google/google_util.h"
75 #include "chrome/browser/lifetime/application_lifetime.h"
76 #include "chrome/browser/policy/browser_policy_connector.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/browser_thread.h"
101 #include "content/public/browser/notification_observer.h"
102 #include "content/public/browser/notification_service.h"
103 #include "content/public/browser/user_metrics.h"
104 #include "content/public/browser/web_contents.h"
105 #include "device/bluetooth/bluetooth_adapter.h"
106 #include "device/bluetooth/bluetooth_adapter_factory.h"
107 #include "device/bluetooth/bluetooth_device.h"
108 #include "grit/ash_strings.h"
109 #include "grit/generated_resources.h"
110 #include "grit/locale_settings.h"
111 #include "net/base/escape.h"
112 #include "third_party/cros_system_api/dbus/service_constants.h"
113 #include "ui/base/l10n/l10n_util.h"
114 #include "ui/base/l10n/time_format.h"
116 using drive::DriveIntegrationService
;
117 using drive::DriveIntegrationServiceFactory
;
123 // The minimum session length limit that can be set.
124 const int kSessionLengthLimitMinMs
= 30 * 1000; // 30 seconds.
126 // The maximum session length limit that can be set.
127 const int kSessionLengthLimitMaxMs
= 24 * 60 * 60 * 1000; // 24 hours.
129 const char kDisplaySettingsSubPageName
[] = "display";
130 const char kDisplayOverscanSettingsSubPageName
[] = "displayOverscan";
132 // The URL for the Google Drive settings page.
133 const char kDriveSettingsPageURL
[] = "https://drive.google.com";
135 void ExtractIMEInfo(const input_method::InputMethodDescriptor
& ime
,
136 const input_method::InputMethodUtil
& util
,
137 ash::IMEInfo
* info
) {
139 info
->name
= util
.GetInputMethodLongName(ime
);
140 info
->medium_name
= util
.GetInputMethodMediumName(ime
);
141 info
->short_name
= util
.GetInputMethodShortName(ime
);
142 info
->third_party
= extension_ime_util::IsExtensionIME(ime
.id());
145 gfx::NativeWindow
GetNativeWindowByStatus(
146 ash::user::LoginStatus login_status
,
147 bool session_started
) {
150 login_status
== ash::user::LOGGED_IN_NONE
||
151 login_status
== ash::user::LOGGED_IN_LOCKED
) ?
152 ash::internal::kShellWindowId_LockSystemModalContainer
:
153 ash::internal::kShellWindowId_SystemModalContainer
;
154 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
158 // Converts drive::JobInfo to ash::DriveOperationStatus.
159 // If the job is not of type that ash tray is interested, returns false.
160 bool ConvertToDriveOperationStatus(const drive::JobInfo
& info
,
161 ash::DriveOperationStatus
* status
) {
162 if (info
.job_type
== drive::TYPE_DOWNLOAD_FILE
) {
163 status
->type
= ash::DriveOperationStatus::OPERATION_DOWNLOAD
;
164 } else if (info
.job_type
== drive::TYPE_UPLOAD_NEW_FILE
||
165 info
.job_type
== drive::TYPE_UPLOAD_EXISTING_FILE
) {
166 status
->type
= ash::DriveOperationStatus::OPERATION_UPLOAD
;
171 if (info
.state
== drive::STATE_NONE
)
172 status
->state
= ash::DriveOperationStatus::OPERATION_NOT_STARTED
;
174 status
->state
= ash::DriveOperationStatus::OPERATION_IN_PROGRESS
;
176 status
->id
= info
.job_id
;
177 status
->file_path
= info
.file_path
;
178 status
->progress
= info
.num_total_bytes
== 0 ? 0.0 :
179 static_cast<double>(info
.num_completed_bytes
) /
180 static_cast<double>(info
.num_total_bytes
);
184 // Converts drive::JobInfo that has finished in |error| state
185 // to ash::DriveOperationStatus.
186 // If the job is not of type that ash tray is interested, returns false.
187 bool ConvertToFinishedDriveOperationStatus(const drive::JobInfo
& info
,
188 drive::FileError error
,
189 ash::DriveOperationStatus
* status
) {
190 if (!ConvertToDriveOperationStatus(info
, status
))
192 status
->state
= (error
== drive::FILE_ERROR_OK
) ?
193 ash::DriveOperationStatus::OPERATION_COMPLETED
:
194 ash::DriveOperationStatus::OPERATION_FAILED
;
198 // Converts a list of drive::JobInfo to a list of ash::DriveOperationStatusList.
199 ash::DriveOperationStatusList
ConvertToDriveStatusList(
200 const std::vector
<drive::JobInfo
>& list
) {
201 ash::DriveOperationStatusList results
;
202 for (size_t i
= 0; i
< list
.size(); ++i
) {
203 ash::DriveOperationStatus status
;
204 if (ConvertToDriveOperationStatus(list
[i
], &status
))
205 results
.push_back(status
);
210 void BluetoothPowerFailure() {
211 // TODO(sad): Show an error bubble?
214 void BluetoothSetDiscoveringError() {
215 LOG(ERROR
) << "BluetoothSetDiscovering failed.";
218 void BluetoothDeviceConnectError(
219 device::BluetoothDevice::ConnectErrorCode error_code
) {
220 // TODO(sad): Do something?
223 // Shows the settings sub page in the last active browser. If there is no such
224 // browser, creates a new browser with the settings sub page.
225 void ShowSettingsSubPageForAppropriateBrowser(
226 const std::string
& sub_page
,
228 chrome::ScopedTabbedBrowserDisplayer
displayer(profile
,
229 chrome::HOST_DESKTOP_TYPE_ASH
);
230 chrome::ShowSettingsSubPage(displayer
.browser(), sub_page
);
233 void ShowNetworkSettingsPage(const std::string
& service_path
) {
234 std::string page
= chrome::kInternetOptionsSubPage
;
235 page
+= "?servicePath=" + net::EscapeUrlEncodedData(service_path
, true);
236 content::RecordAction(
237 base::UserMetricsAction("OpenInternetOptionsDialog"));
238 ShowSettingsSubPageForAppropriateBrowser(
240 ProfileManager::GetPrimaryUserProfile());
243 void OnAcceptMultiprofilesIntro(bool no_show_again
) {
244 PrefService
* prefs
= ProfileManager::GetActiveUserProfile()->GetPrefs();
245 prefs
->SetBoolean(prefs::kMultiProfileNeverShowIntro
, no_show_again
);
246 UserAddingScreen::Get()->Start();
249 class SystemTrayDelegate
: public ash::SystemTrayDelegate
,
250 public SessionManagerClient::Observer
,
251 public drive::JobListObserver
,
252 public content::NotificationObserver
,
253 public input_method::InputMethodManager::Observer
,
254 public chromeos::LoginState::Observer
,
255 public device::BluetoothAdapter::Observer
,
256 public SystemKeyEventListener::CapsLockObserver
,
257 public policy::CloudPolicyStore::Observer
,
258 public ash::SessionStateObserver
{
261 : ui_weak_ptr_factory_(
262 new base::WeakPtrFactory
<SystemTrayDelegate
>(this)),
264 clock_type_(base::GetHourClockType()),
265 search_key_mapped_to_(input_method::kSearchKey
),
266 screen_locked_(false),
267 have_session_start_time_(false),
268 have_session_length_limit_(false),
269 volume_control_delegate_(new VolumeController()) {
270 // Register notifications on construction so that events such as
271 // PROFILE_CREATED do not get missed if they happen before Initialize().
272 registrar_
.reset(new content::NotificationRegistrar
);
273 registrar_
->Add(this,
274 chrome::NOTIFICATION_UPGRADE_RECOMMENDED
,
275 content::NotificationService::AllSources());
276 registrar_
->Add(this,
277 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
,
278 content::NotificationService::AllSources());
279 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE
) {
280 registrar_
->Add(this,
281 chrome::NOTIFICATION_SESSION_STARTED
,
282 content::NotificationService::AllSources());
284 registrar_
->Add(this,
285 chrome::NOTIFICATION_PROFILE_CREATED
,
286 content::NotificationService::AllSources());
287 registrar_
->Add(this,
288 chrome::NOTIFICATION_PROFILE_DESTROYED
,
289 content::NotificationService::AllSources());
292 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER
,
293 content::NotificationService::AllSources());
296 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
,
297 content::NotificationService::AllSources());
300 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
,
301 content::NotificationService::AllSources());
304 virtual void Initialize() OVERRIDE
{
305 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
307 input_method::InputMethodManager::Get()->AddObserver(this);
310 if (SystemKeyEventListener::GetInstance())
311 SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this);
313 device::BluetoothAdapterFactory::GetAdapter(
314 base::Bind(&SystemTrayDelegate::InitializeOnAdapterReady
,
315 ui_weak_ptr_factory_
->GetWeakPtr()));
317 ash::Shell::GetInstance()->session_state_delegate()->
318 AddSessionStateObserver(this);
320 if (LoginState::IsInitialized())
321 LoginState::Get()->AddObserver(this);
324 virtual void Shutdown() OVERRIDE
{
327 void InitializeOnAdapterReady(
328 scoped_refptr
<device::BluetoothAdapter
> adapter
) {
329 bluetooth_adapter_
= adapter
;
330 CHECK(bluetooth_adapter_
.get());
331 bluetooth_adapter_
->AddObserver(this);
333 local_state_registrar_
.reset(new PrefChangeRegistrar
);
334 local_state_registrar_
->Init(g_browser_process
->local_state());
336 UpdateSessionStartTime();
337 UpdateSessionLengthLimit();
339 local_state_registrar_
->Add(
340 prefs::kSessionStartTime
,
341 base::Bind(&SystemTrayDelegate::UpdateSessionStartTime
,
342 base::Unretained(this)));
343 local_state_registrar_
->Add(
344 prefs::kSessionLengthLimit
,
345 base::Bind(&SystemTrayDelegate::UpdateSessionLengthLimit
,
346 base::Unretained(this)));
348 policy::BrowserPolicyConnector
* policy_connector
=
349 g_browser_process
->browser_policy_connector();
350 policy::DeviceCloudPolicyManagerChromeOS
* policy_manager
=
351 policy_connector
->GetDeviceCloudPolicyManager();
353 policy_manager
->core()->store()->AddObserver(this);
354 UpdateEnterpriseDomain();
357 virtual ~SystemTrayDelegate() {
358 // Unregister PrefChangeRegistrars.
359 local_state_registrar_
.reset();
360 user_pref_registrar_
.reset();
362 // Unregister content notifications befure destroying any components.
365 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
366 input_method::InputMethodManager::Get()->RemoveObserver(this);
367 if (SystemKeyEventListener::GetInstance())
368 SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this);
369 bluetooth_adapter_
->RemoveObserver(this);
370 ash::Shell::GetInstance()->session_state_delegate()->
371 RemoveSessionStateObserver(this);
372 LoginState::Get()->RemoveObserver(this);
374 // Stop observing Drive operations.
375 UnobserveDriveUpdates();
377 policy::DeviceCloudPolicyManagerChromeOS
* policy_manager
=
378 g_browser_process
->browser_policy_connector()->
379 GetDeviceCloudPolicyManager();
381 policy_manager
->core()->store()->RemoveObserver(this);
384 // Overridden from ash::SystemTrayDelegate:
385 virtual bool GetTrayVisibilityOnStartup() OVERRIDE
{
386 // In case of OOBE / sign in screen tray will be shown later.
387 return LoginState::Get()->IsUserLoggedIn();
390 virtual ash::user::LoginStatus
GetUserLoginStatus() const OVERRIDE
{
391 // All non-logged in ChromeOS specific LOGGED_IN states map to the same
392 // Ash specific LOGGED_IN state.
393 if (!LoginState::Get()->IsUserLoggedIn())
394 return ash::user::LOGGED_IN_NONE
;
397 return ash::user::LOGGED_IN_LOCKED
;
399 LoginState::LoggedInUserType user_type
=
400 LoginState::Get()->GetLoggedInUserType();
402 case LoginState::LOGGED_IN_USER_NONE
:
403 return ash::user::LOGGED_IN_NONE
;
404 case LoginState::LOGGED_IN_USER_REGULAR
:
405 return ash::user::LOGGED_IN_USER
;
406 case LoginState::LOGGED_IN_USER_OWNER
:
407 return ash::user::LOGGED_IN_OWNER
;
408 case LoginState::LOGGED_IN_USER_GUEST
:
409 return ash::user::LOGGED_IN_GUEST
;
410 case LoginState::LOGGED_IN_USER_RETAIL_MODE
:
411 return ash::user::LOGGED_IN_RETAIL_MODE
;
412 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT
:
413 return ash::user::LOGGED_IN_PUBLIC
;
414 case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED
:
415 return ash::user::LOGGED_IN_LOCALLY_MANAGED
;
416 case LoginState::LOGGED_IN_USER_KIOSK_APP
:
417 return ash::user::LOGGED_IN_KIOSK_APP
;
420 return ash::user::LOGGED_IN_NONE
;
423 virtual bool IsOobeCompleted() const OVERRIDE
{
424 if (!base::SysInfo::IsRunningOnChromeOS() &&
425 LoginState::Get()->IsUserLoggedIn())
427 return StartupUtils::IsOobeCompleted();
430 virtual void ChangeProfilePicture() OVERRIDE
{
431 content::RecordAction(
432 base::UserMetricsAction("OpenChangeProfilePictureDialog"));
433 ShowSettingsSubPageForAppropriateBrowser(
434 chrome::kChangeProfilePictureSubPage
,
435 ProfileManager::GetActiveUserProfile());
438 virtual const std::string
GetEnterpriseDomain() const OVERRIDE
{
439 return enterprise_domain_
;
442 virtual const base::string16
GetEnterpriseMessage() const OVERRIDE
{
443 if (GetEnterpriseDomain().empty())
444 return base::string16();
445 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE
,
446 base::UTF8ToUTF16(GetEnterpriseDomain()));
449 virtual const std::string
GetLocallyManagedUserManager() const OVERRIDE
{
450 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
451 return std::string();
452 return UserManager::Get()->GetSupervisedUserManager()->
453 GetManagerDisplayEmail(
454 chromeos::UserManager::Get()->GetActiveUser()->email());
457 virtual const base::string16
458 GetLocallyManagedUserManagerName() const OVERRIDE
{
459 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
460 return base::string16();
461 return UserManager::Get()->GetSupervisedUserManager()->
462 GetManagerDisplayName(
463 chromeos::UserManager::Get()->GetActiveUser()->email());
466 virtual const base::string16
GetLocallyManagedUserMessage() const OVERRIDE
{
467 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
468 return base::string16();
469 return l10n_util::GetStringFUTF16(
470 IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE
,
471 base::UTF8ToUTF16(GetLocallyManagedUserManager()));
474 virtual bool SystemShouldUpgrade() const OVERRIDE
{
475 return UpgradeDetector::GetInstance()->notify_upgrade();
478 virtual base::HourClockType
GetHourClockType() const OVERRIDE
{
482 virtual void ShowSettings() OVERRIDE
{
483 chrome::ScopedTabbedBrowserDisplayer
displayer(
484 ProfileManager::GetActiveUserProfile(),
485 chrome::HOST_DESKTOP_TYPE_ASH
);
486 chrome::ShowSettings(displayer
.browser());
489 virtual bool ShouldShowSettings() OVERRIDE
{
490 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings();
493 virtual void ShowDateSettings() OVERRIDE
{
494 content::RecordAction(base::UserMetricsAction("ShowDateOptions"));
495 std::string sub_page
= std::string(chrome::kSearchSubPage
) + "#" +
496 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME
);
497 // Everybody can change the time zone (even though it is a device setting).
498 ShowSettingsSubPageForAppropriateBrowser(
500 ProfileManager::GetActiveUserProfile());
503 virtual void ShowNetworkSettings(const std::string
& service_path
) OVERRIDE
{
504 if (!LoginState::Get()->IsUserLoggedIn())
506 ShowNetworkSettingsPage(service_path
);
509 virtual void ShowBluetoothSettings() OVERRIDE
{
510 // TODO(sad): Make this work.
513 virtual void ShowDisplaySettings() OVERRIDE
{
514 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions"));
515 ShowSettingsSubPageForAppropriateBrowser(
516 kDisplaySettingsSubPageName
,
517 ProfileManager::GetActiveUserProfile());
520 virtual void ShowChromeSlow() OVERRIDE
{
521 chrome::ScopedTabbedBrowserDisplayer
displayer(
522 ProfileManager::GetPrimaryUserProfile(),
523 chrome::HOST_DESKTOP_TYPE_ASH
);
524 chrome::ShowSlow(displayer
.browser());
527 virtual bool ShouldShowDisplayNotification() OVERRIDE
{
528 // Packaged app is not counted as 'last active', so if a browser opening the
529 // display settings is in background of a packaged app, it will return true.
530 // TODO(mukai): fix this.
531 Browser
* active_browser
= chrome::FindLastActiveWithHostDesktopType(
532 chrome::HOST_DESKTOP_TYPE_ASH
);
536 content::WebContents
* active_contents
=
537 active_browser
->tab_strip_model()->GetActiveWebContents();
538 if (!active_contents
)
541 GURL visible_url
= active_contents
->GetLastCommittedURL();
542 std::string display_settings_url
=
543 std::string(chrome::kChromeUISettingsURL
) + kDisplaySettingsSubPageName
;
544 std::string display_overscan_url
=
545 std::string(chrome::kChromeUISettingsURL
) +
546 kDisplayOverscanSettingsSubPageName
;
547 return (visible_url
.spec() != display_settings_url
) &&
548 (visible_url
.spec() != display_overscan_url
);
551 virtual void ShowDriveSettings() OVERRIDE
{
552 // TODO(tengs): Open the drive-specific settings page once we put it in.
553 // For now just show Google Drive main page.
554 chrome::ScopedTabbedBrowserDisplayer
displayer(
555 ProfileManager::GetActiveUserProfile(),
556 chrome::HOST_DESKTOP_TYPE_ASH
);
557 chrome::ShowSingletonTabOverwritingNTP(
559 chrome::GetSingletonTabNavigateParams(displayer
.browser(),
560 GURL(kDriveSettingsPageURL
)));
563 virtual void ShowIMESettings() OVERRIDE
{
564 content::RecordAction(
565 base::UserMetricsAction("OpenLanguageOptionsDialog"));
566 ShowSettingsSubPageForAppropriateBrowser(
567 chrome::kLanguageOptionsSubPage
,
568 ProfileManager::GetActiveUserProfile());
571 virtual void ShowHelp() OVERRIDE
{
572 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(),
573 chrome::HOST_DESKTOP_TYPE_ASH
,
574 chrome::HELP_SOURCE_MENU
);
577 virtual void ShowAccessibilityHelp() OVERRIDE
{
578 chrome::ScopedTabbedBrowserDisplayer
displayer(
579 ProfileManager::GetActiveUserProfile(),
580 chrome::HOST_DESKTOP_TYPE_ASH
);
581 accessibility::ShowAccessibilityHelp(displayer
.browser());
584 virtual void ShowAccessibilitySettings() OVERRIDE
{
585 content::RecordAction(
586 base::UserMetricsAction("ShowAccessibilitySettings"));
587 std::string sub_page
= std::string(chrome::kSearchSubPage
) + "#" +
588 l10n_util::GetStringUTF8(
589 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY
);
590 ShowSettingsSubPageForAppropriateBrowser(
592 ProfileManager::GetActiveUserProfile());
595 virtual void ShowPublicAccountInfo() OVERRIDE
{
596 chrome::ScopedTabbedBrowserDisplayer
displayer(
597 ProfileManager::GetActiveUserProfile(),
598 chrome::HOST_DESKTOP_TYPE_ASH
);
599 chrome::ShowPolicy(displayer
.browser());
602 virtual void ShowLocallyManagedUserInfo() OVERRIDE
{
603 // TODO(antrim): find out what should we show in this case.
604 // http://crbug.com/229762
607 virtual void ShowEnterpriseInfo() OVERRIDE
{
608 ash::user::LoginStatus status
= GetUserLoginStatus();
609 if (status
== ash::user::LOGGED_IN_NONE
||
610 status
== ash::user::LOGGED_IN_LOCKED
) {
611 scoped_refptr
<chromeos::HelpAppLauncher
> help_app(
612 new chromeos::HelpAppLauncher(GetNativeWindow()));
613 help_app
->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE
);
615 GURL
url(google_util::StringAppendGoogleLocaleParam(
616 chrome::kLearnMoreEnterpriseURL
));
617 chrome::ScopedTabbedBrowserDisplayer
displayer(
618 ProfileManager::GetActiveUserProfile(),
619 chrome::HOST_DESKTOP_TYPE_ASH
);
620 chrome::ShowSingletonTab(displayer
.browser(), url
);
624 virtual void ShowUserLogin() OVERRIDE
{
625 ash::Shell
* shell
= ash::Shell::GetInstance();
626 if (!shell
->delegate()->IsMultiProfilesEnabled())
629 // Only regular users could add other users to current session.
630 if (UserManager::Get()->GetActiveUser()->GetType() !=
631 User::USER_TYPE_REGULAR
) {
635 if (static_cast<int>(UserManager::Get()->GetLoggedInUsers().size()) >=
636 shell
->session_state_delegate()->GetMaximumNumberOfLoggedInUsers())
639 // Launch sign in screen to add another user to current session.
640 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) {
641 // Don't show dialog if any logged in user in multi-profiles session
643 bool show_intro
= true;
644 const UserList logged_in_users
= UserManager::Get()->GetLoggedInUsers();
645 for (UserList::const_iterator it
= logged_in_users
.begin();
646 it
!= logged_in_users
.end(); ++it
) {
647 show_intro
&= !multi_user_util::GetProfileFromUserID(
648 multi_user_util::GetUserIDFromEmail((*it
)->email()))->GetPrefs()->
649 GetBoolean(prefs::kMultiProfileNeverShowIntro
);
654 base::Callback
<void(bool)> on_accept
=
655 base::Bind(&OnAcceptMultiprofilesIntro
);
656 ShowMultiprofilesIntroDialog(on_accept
);
658 UserAddingScreen::Get()->Start();
663 virtual void ShowSpringChargerReplacementDialog() OVERRIDE
{
664 if (!ChargerReplacementDialog::ShouldShowDialog())
667 ChargerReplacementDialog
* dialog
=
668 new ChargerReplacementDialog(GetNativeWindow());
672 virtual bool HasUserConfirmedSafeSpringCharger() OVERRIDE
{
673 return ChargerReplacementHandler::GetChargerStatusPref() ==
674 ChargerReplacementHandler::CONFIRM_SAFE_CHARGER
;
677 virtual void ShutDown() OVERRIDE
{
678 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
681 virtual void SignOut() OVERRIDE
{
682 chrome::AttemptUserExit();
685 virtual void RequestLockScreen() OVERRIDE
{
686 // TODO(antrim) : additional logging for crbug/173178
687 LOG(WARNING
) << "Requesting screen lock from AshSystemTrayDelegate";
688 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
691 virtual void RequestRestartForUpdate() OVERRIDE
{
692 // We expect that UpdateEngine is in "Reboot for update" state now.
693 chrome::NotifyAndTerminate(true /* fast path */);
696 virtual void GetAvailableBluetoothDevices(
697 ash::BluetoothDeviceList
* list
) OVERRIDE
{
698 device::BluetoothAdapter::DeviceList devices
=
699 bluetooth_adapter_
->GetDevices();
700 for (size_t i
= 0; i
< devices
.size(); ++i
) {
701 device::BluetoothDevice
* device
= devices
[i
];
702 ash::BluetoothDeviceInfo info
;
703 info
.address
= device
->GetAddress();
704 info
.display_name
= device
->GetName();
705 info
.connected
= device
->IsConnected();
706 info
.connecting
= device
->IsConnecting();
707 info
.paired
= device
->IsPaired();
708 list
->push_back(info
);
712 virtual void BluetoothStartDiscovering() OVERRIDE
{
713 bluetooth_adapter_
->StartDiscovering(
714 base::Bind(&base::DoNothing
),
715 base::Bind(&BluetoothSetDiscoveringError
));
718 virtual void BluetoothStopDiscovering() OVERRIDE
{
719 bluetooth_adapter_
->StopDiscovering(
720 base::Bind(&base::DoNothing
),
721 base::Bind(&BluetoothSetDiscoveringError
));
724 virtual void ConnectToBluetoothDevice(const std::string
& address
) OVERRIDE
{
725 device::BluetoothDevice
* device
= bluetooth_adapter_
->GetDevice(address
);
726 if (!device
|| device
->IsConnecting() ||
727 (device
->IsConnected() && device
->IsPaired())) {
730 if (device
->IsPaired() && !device
->IsConnectable())
732 if (device
->IsPaired() || !device
->IsPairable()) {
733 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
734 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE
);
737 base::Bind(&base::DoNothing
),
738 base::Bind(&BluetoothDeviceConnectError
));
739 } else { // Show paring dialog for the unpaired device.
740 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
741 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE
);
742 BluetoothPairingDialog
* dialog
=
743 new BluetoothPairingDialog(GetNativeWindow(), device
);
744 // The dialog deletes itself on close.
749 virtual bool IsBluetoothDiscovering() OVERRIDE
{
750 return bluetooth_adapter_
->IsDiscovering();
753 virtual void GetCurrentIME(ash::IMEInfo
* info
) OVERRIDE
{
754 input_method::InputMethodManager
* manager
=
755 input_method::InputMethodManager::Get();
756 input_method::InputMethodUtil
* util
= manager
->GetInputMethodUtil();
757 input_method::InputMethodDescriptor ime
= manager
->GetCurrentInputMethod();
758 ExtractIMEInfo(ime
, *util
, info
);
759 info
->selected
= true;
762 virtual void GetAvailableIMEList(ash::IMEInfoList
* list
) OVERRIDE
{
763 input_method::InputMethodManager
* manager
=
764 input_method::InputMethodManager::Get();
765 input_method::InputMethodUtil
* util
= manager
->GetInputMethodUtil();
766 scoped_ptr
<input_method::InputMethodDescriptors
> ime_descriptors(
767 manager
->GetActiveInputMethods());
768 std::string current
= manager
->GetCurrentInputMethod().id();
769 for (size_t i
= 0; i
< ime_descriptors
->size(); i
++) {
770 input_method::InputMethodDescriptor
& ime
= ime_descriptors
->at(i
);
772 ExtractIMEInfo(ime
, *util
, &info
);
773 info
.selected
= ime
.id() == current
;
774 list
->push_back(info
);
778 virtual void GetCurrentIMEProperties(
779 ash::IMEPropertyInfoList
* list
) OVERRIDE
{
780 input_method::InputMethodManager
* manager
=
781 input_method::InputMethodManager::Get();
782 input_method::InputMethodPropertyList properties
=
783 manager
->GetCurrentInputMethodProperties();
784 for (size_t i
= 0; i
< properties
.size(); ++i
) {
785 ash::IMEPropertyInfo property
;
786 property
.key
= properties
[i
].key
;
787 property
.name
= base::UTF8ToUTF16(properties
[i
].label
);
788 property
.selected
= properties
[i
].is_selection_item_checked
;
789 list
->push_back(property
);
793 virtual void SwitchIME(const std::string
& ime_id
) OVERRIDE
{
794 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id
);
797 virtual void ActivateIMEProperty(const std::string
& key
) OVERRIDE
{
798 input_method::InputMethodManager::Get()->
799 ActivateInputMethodProperty(key
);
802 virtual void CancelDriveOperation(int32 operation_id
) OVERRIDE
{
803 DriveIntegrationService
* integration_service
=
804 FindDriveIntegrationService();
805 if (!integration_service
)
808 integration_service
->job_list()->CancelJob(operation_id
);
811 virtual void GetDriveOperationStatusList(
812 ash::DriveOperationStatusList
* list
) OVERRIDE
{
813 DriveIntegrationService
* integration_service
=
814 FindDriveIntegrationService();
815 if (!integration_service
)
818 *list
= ConvertToDriveStatusList(
819 integration_service
->job_list()->GetJobInfoList());
822 virtual void ShowNetworkConfigure(const std::string
& network_id
,
823 gfx::NativeWindow parent_window
) OVERRIDE
{
824 NetworkConfigView::Show(network_id
, parent_window
);
827 virtual bool EnrollNetwork(const std::string
& network_id
,
828 gfx::NativeWindow parent_window
) OVERRIDE
{
829 return enrollment::CreateDialog(network_id
, parent_window
);
832 virtual void ManageBluetoothDevices() OVERRIDE
{
833 content::RecordAction(
834 base::UserMetricsAction("ShowBluetoothSettingsPage"));
835 std::string sub_page
= std::string(chrome::kSearchSubPage
) + "#" +
836 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH
);
837 ShowSettingsSubPageForAppropriateBrowser(
839 ProfileManager::GetPrimaryUserProfile());
842 virtual void ToggleBluetooth() OVERRIDE
{
843 bluetooth_adapter_
->SetPowered(!bluetooth_adapter_
->IsPowered(),
844 base::Bind(&base::DoNothing
),
845 base::Bind(&BluetoothPowerFailure
));
848 virtual void ShowMobileSimDialog() OVERRIDE
{
849 SimDialogDelegate::ShowDialog(GetNativeWindow(),
850 SimDialogDelegate::SIM_DIALOG_UNLOCK
);
853 virtual void ShowMobileSetupDialog(const std::string
& service_path
) OVERRIDE
{
854 MobileSetupDialog::Show(service_path
);
857 virtual void ShowOtherNetworkDialog(const std::string
& type
) OVERRIDE
{
858 if (type
== shill::kTypeCellular
) {
859 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
862 NetworkConfigView::ShowForType(type
, GetNativeWindow());
865 virtual bool GetBluetoothAvailable() OVERRIDE
{
866 return bluetooth_adapter_
->IsPresent();
869 virtual bool GetBluetoothEnabled() OVERRIDE
{
870 return bluetooth_adapter_
->IsPowered();
873 virtual void ChangeProxySettings() OVERRIDE
{
874 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE
);
875 LoginDisplayHostImpl::default_host()->OpenProxySettings();
878 virtual ash::VolumeControlDelegate
*
879 GetVolumeControlDelegate() const OVERRIDE
{
880 return volume_control_delegate_
.get();
883 virtual void SetVolumeControlDelegate(
884 scoped_ptr
<ash::VolumeControlDelegate
> delegate
) OVERRIDE
{
885 volume_control_delegate_
.swap(delegate
);
888 virtual bool GetSessionStartTime(
889 base::TimeTicks
* session_start_time
) OVERRIDE
{
890 *session_start_time
= session_start_time_
;
891 return have_session_start_time_
;
894 virtual bool GetSessionLengthLimit(
895 base::TimeDelta
* session_length_limit
) OVERRIDE
{
896 *session_length_limit
= session_length_limit_
;
897 return have_session_length_limit_
;
900 virtual int GetSystemTrayMenuWidth() OVERRIDE
{
901 return l10n_util::GetLocalizedContentsWidthInPixels(
902 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS
);
906 ash::SystemTray
* GetPrimarySystemTray() {
907 return ash::Shell::GetInstance()->GetPrimarySystemTray();
910 ash::SystemTrayNotifier
* GetSystemTrayNotifier() {
911 return ash::Shell::GetInstance()->system_tray_notifier();
914 void SetProfile(Profile
* profile
) {
915 // Stop observing the current |user_profile_| on Drive integration status.
916 UnobserveDriveUpdates();
918 user_profile_
= profile
;
920 // Restart observation, now for the newly set |profile|.
921 ObserveDriveUpdates();
923 PrefService
* prefs
= profile
->GetPrefs();
924 user_pref_registrar_
.reset(new PrefChangeRegistrar
);
925 user_pref_registrar_
->Init(prefs
);
926 user_pref_registrar_
->Add(
927 prefs::kUse24HourClock
,
928 base::Bind(&SystemTrayDelegate::UpdateClockType
,
929 base::Unretained(this)));
930 user_pref_registrar_
->Add(
931 prefs::kLanguageRemapSearchKeyTo
,
932 base::Bind(&SystemTrayDelegate::OnLanguageRemapSearchKeyToChanged
,
933 base::Unretained(this)));
934 user_pref_registrar_
->Add(
935 prefs::kShowLogoutButtonInTray
,
936 base::Bind(&SystemTrayDelegate::UpdateShowLogoutButtonInTray
,
937 base::Unretained(this)));
938 user_pref_registrar_
->Add(
939 prefs::kLogoutDialogDurationMs
,
940 base::Bind(&SystemTrayDelegate::UpdateLogoutDialogDuration
,
941 base::Unretained(this)));
942 user_pref_registrar_
->Add(
943 prefs::kLargeCursorEnabled
,
944 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged
,
945 base::Unretained(this),
946 ash::A11Y_NOTIFICATION_NONE
));
947 user_pref_registrar_
->Add(
948 prefs::kAutoclickEnabled
,
949 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged
,
950 base::Unretained(this),
951 ash::A11Y_NOTIFICATION_NONE
));
952 user_pref_registrar_
->Add(
953 prefs::kShouldAlwaysShowAccessibilityMenu
,
954 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged
,
955 base::Unretained(this),
956 ash::A11Y_NOTIFICATION_NONE
));
957 user_pref_registrar_
->Add(
958 prefs::kPerformanceTracingEnabled
,
959 base::Bind(&SystemTrayDelegate::UpdatePerformanceTracing
,
960 base::Unretained(this)));
963 UpdateShowLogoutButtonInTray();
964 UpdateLogoutDialogDuration();
965 UpdatePerformanceTracing();
966 search_key_mapped_to_
=
967 profile
->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo
);
970 bool UnsetProfile(Profile
* profile
) {
971 if (profile
!= user_profile_
)
973 user_pref_registrar_
.reset();
977 void ObserveDriveUpdates() {
978 DriveIntegrationService
* integration_service
=
979 FindDriveIntegrationService();
980 if (integration_service
)
981 integration_service
->job_list()->AddObserver(this);
984 void UnobserveDriveUpdates() {
985 DriveIntegrationService
* integration_service
=
986 FindDriveIntegrationService();
987 if (integration_service
)
988 integration_service
->job_list()->RemoveObserver(this);
991 bool ShouldUse24HourClock() const {
992 // On login screen and in guest mode owner default is used for
993 // kUse24HourClock preference.
994 const ash::user::LoginStatus status
= GetUserLoginStatus();
995 const CrosSettings
* const cros_settings
= CrosSettings::Get();
996 bool system_use_24_hour_clock
= true;
997 const bool system_value_found
= cros_settings
->GetBoolean(
998 kSystemUse24HourClock
, &system_use_24_hour_clock
);
1000 if (status
== ash::user::LOGGED_IN_NONE
)
1001 return (system_value_found
1002 ? system_use_24_hour_clock
1003 : (base::GetHourClockType() == base::k24HourClock
));
1005 const PrefService::Preference
* user_pref
=
1006 user_pref_registrar_
->prefs()->FindPreference(prefs::kUse24HourClock
);
1007 if (status
== ash::user::LOGGED_IN_GUEST
&& user_pref
->IsDefaultValue())
1008 return (system_value_found
1009 ? system_use_24_hour_clock
1010 : (base::GetHourClockType() == base::k24HourClock
));
1012 bool use_24_hour_clock
= true;
1013 user_pref
->GetValue()->GetAsBoolean(&use_24_hour_clock
);
1014 return use_24_hour_clock
;
1017 void UpdateClockType() {
1018 if (!user_pref_registrar_
)
1021 const bool use_24_hour_clock
= ShouldUse24HourClock();
1022 clock_type_
= use_24_hour_clock
? base::k24HourClock
: base::k12HourClock
;
1023 GetSystemTrayNotifier()->NotifyDateFormatChanged();
1024 // This also works for enterprise-managed devices because they never have
1026 if (chromeos::UserManager::Get()->IsCurrentUserOwner())
1027 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock
, use_24_hour_clock
);
1030 void UpdateShowLogoutButtonInTray() {
1031 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
1032 user_pref_registrar_
->prefs()->GetBoolean(
1033 prefs::kShowLogoutButtonInTray
));
1036 void UpdateLogoutDialogDuration() {
1037 const int duration_ms
= user_pref_registrar_
->prefs()->GetInteger(
1038 prefs::kLogoutDialogDurationMs
);
1039 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged(
1040 base::TimeDelta::FromMilliseconds(duration_ms
));
1043 void UpdateSessionStartTime() {
1044 const PrefService
* local_state
= local_state_registrar_
->prefs();
1045 if (local_state
->HasPrefPath(prefs::kSessionStartTime
)) {
1046 have_session_start_time_
= true;
1047 session_start_time_
= base::TimeTicks::FromInternalValue(
1048 local_state
->GetInt64(prefs::kSessionStartTime
));
1050 have_session_start_time_
= false;
1051 session_start_time_
= base::TimeTicks();
1053 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
1056 void UpdateSessionLengthLimit() {
1057 const PrefService
* local_state
= local_state_registrar_
->prefs();
1058 if (local_state
->HasPrefPath(prefs::kSessionLengthLimit
)) {
1059 have_session_length_limit_
= true;
1060 session_length_limit_
= base::TimeDelta::FromMilliseconds(
1061 std::min(std::max(local_state
->GetInteger(prefs::kSessionLengthLimit
),
1062 kSessionLengthLimitMinMs
),
1063 kSessionLengthLimitMaxMs
));
1065 have_session_length_limit_
= false;
1066 session_length_limit_
= base::TimeDelta();
1068 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
1071 // LoginState::Observer overrides.
1072 virtual void LoggedInStateChanged() OVERRIDE
{
1073 // It apparently sometimes takes a while after login before the current user
1074 // is recognized as the owner. Make sure that the system-wide clock setting
1075 // is updated when the recognition eventually happens
1076 // (http://crbug.com/278601).
1078 // Note that it isn't safe to blindly call UpdateClockType() from this
1079 // method, as LoggedInStateChanged() is also called before the logged-in
1080 // user's profile has actually been loaded (http://crbug.com/317745). The
1081 // system tray's time format is updated at login via SetProfile().
1082 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) {
1083 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock
,
1084 ShouldUse24HourClock());
1088 // Overridden from SessionManagerClient::Observer.
1089 virtual void LockScreen() OVERRIDE
{
1090 screen_locked_
= true;
1091 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1092 GetUserLoginStatus());
1095 virtual void ScreenIsUnlocked() OVERRIDE
{
1096 screen_locked_
= false;
1097 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1098 GetUserLoginStatus());
1101 gfx::NativeWindow
GetNativeWindow() const {
1102 bool session_started
= ash::Shell::GetInstance()->session_state_delegate()
1103 ->IsActiveUserSessionStarted();
1104 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started
);
1107 // content::NotificationObserver implementation.
1108 virtual void Observe(int type
,
1109 const content::NotificationSource
& source
,
1110 const content::NotificationDetails
& details
) OVERRIDE
{
1112 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED
: {
1113 UpgradeDetector
* detector
=
1114 content::Source
<UpgradeDetector
>(source
).ptr();
1115 ash::UpdateObserver::UpdateSeverity severity
=
1116 ash::UpdateObserver::UPDATE_NORMAL
;
1117 switch (detector
->upgrade_notification_stage()) {
1118 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE
:
1119 severity
= ash::UpdateObserver::UPDATE_SEVERE_RED
;
1122 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH
:
1123 severity
= ash::UpdateObserver::UPDATE_HIGH_ORANGE
;
1126 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED
:
1127 severity
= ash::UpdateObserver::UPDATE_LOW_GREEN
;
1130 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW
:
1132 severity
= ash::UpdateObserver::UPDATE_NORMAL
;
1135 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity
);
1138 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
: {
1139 // This notification is also sent on login screen when user avatar
1140 // is loaded from file.
1141 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE
) {
1142 GetSystemTrayNotifier()->NotifyUserUpdate();
1146 case chrome::NOTIFICATION_PROFILE_CREATED
: {
1147 SetProfile(content::Source
<Profile
>(source
).ptr());
1148 registrar_
->Remove(this,
1149 chrome::NOTIFICATION_PROFILE_CREATED
,
1150 content::NotificationService::AllSources());
1153 case chrome::NOTIFICATION_PROFILE_DESTROYED
: {
1154 if (UnsetProfile(content::Source
<Profile
>(source
).ptr())) {
1155 registrar_
->Remove(this,
1156 chrome::NOTIFICATION_PROFILE_DESTROYED
,
1157 content::NotificationService::AllSources());
1161 case chrome::NOTIFICATION_SESSION_STARTED
: {
1162 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1163 GetUserLoginStatus());
1164 SetProfile(ProfileManager::GetActiveUserProfile());
1167 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
:
1168 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
:
1169 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER
: {
1170 AccessibilityStatusEventDetails
* accessibility_status
=
1171 content::Details
<AccessibilityStatusEventDetails
>(details
).ptr();
1172 OnAccessibilityModeChanged(accessibility_status
->notify
);
1180 void OnLanguageRemapSearchKeyToChanged() {
1181 search_key_mapped_to_
= user_pref_registrar_
->prefs()->GetInteger(
1182 prefs::kLanguageRemapSearchKeyTo
);
1185 void OnAccessibilityModeChanged(
1186 ash::AccessibilityNotificationVisibility notify
) {
1187 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify
);
1190 void UpdatePerformanceTracing() {
1191 if (!user_pref_registrar_
)
1194 user_pref_registrar_
->prefs()->GetBoolean(
1195 prefs::kPerformanceTracingEnabled
);
1196 GetSystemTrayNotifier()->NotifyTracingModeChanged(value
);
1199 // Overridden from InputMethodManager::Observer.
1200 virtual void InputMethodChanged(
1201 input_method::InputMethodManager
* manager
, bool show_message
) OVERRIDE
{
1202 // |show_message| in ash means the message_center notifications
1203 // which should not be shown unless kDisableIMEModeIndicator is
1204 // on, since the mode indicator already notifies the user.
1205 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1206 switches::kDisableIMEModeIndicator
)) {
1207 show_message
= false;
1209 GetSystemTrayNotifier()->NotifyRefreshIME(show_message
);
1212 virtual void InputMethodPropertyChanged(
1213 input_method::InputMethodManager
* manager
) OVERRIDE
{
1214 GetSystemTrayNotifier()->NotifyRefreshIME(false);
1217 // drive::JobListObserver overrides.
1218 virtual void OnJobAdded(const drive::JobInfo
& job_info
) OVERRIDE
{
1219 OnJobUpdated(job_info
);
1222 virtual void OnJobDone(const drive::JobInfo
& job_info
,
1223 drive::FileError error
) OVERRIDE
{
1224 ash::DriveOperationStatus status
;
1225 if (ConvertToFinishedDriveOperationStatus(job_info
, error
, &status
))
1226 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status
);
1229 virtual void OnJobUpdated(const drive::JobInfo
& job_info
) OVERRIDE
{
1230 ash::DriveOperationStatus status
;
1231 if (ConvertToDriveOperationStatus(job_info
, &status
))
1232 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status
);
1235 DriveIntegrationService
* FindDriveIntegrationService() {
1236 return user_profile_
?
1237 DriveIntegrationServiceFactory::FindForProfile(user_profile_
) : NULL
;
1240 // Overridden from BluetoothAdapter::Observer.
1241 virtual void AdapterPresentChanged(device::BluetoothAdapter
* adapter
,
1242 bool present
) OVERRIDE
{
1243 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1246 virtual void AdapterPoweredChanged(device::BluetoothAdapter
* adapter
,
1247 bool powered
) OVERRIDE
{
1248 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1251 virtual void AdapterDiscoveringChanged(device::BluetoothAdapter
* adapter
,
1252 bool discovering
) OVERRIDE
{
1253 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1256 virtual void DeviceAdded(device::BluetoothAdapter
* adapter
,
1257 device::BluetoothDevice
* device
) OVERRIDE
{
1258 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1261 virtual void DeviceChanged(device::BluetoothAdapter
* adapter
,
1262 device::BluetoothDevice
* device
) OVERRIDE
{
1263 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1266 virtual void DeviceRemoved(device::BluetoothAdapter
* adapter
,
1267 device::BluetoothDevice
* device
) OVERRIDE
{
1268 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1271 // Overridden from SystemKeyEventListener::CapsLockObserver.
1272 virtual void OnCapsLockChange(bool enabled
) OVERRIDE
{
1273 bool search_mapped_to_caps_lock
= false;
1274 if (!base::SysInfo::IsRunningOnChromeOS() ||
1275 search_key_mapped_to_
== input_method::kCapsLockKey
)
1276 search_mapped_to_caps_lock
= true;
1277 GetSystemTrayNotifier()->NotifyCapsLockChanged(
1278 enabled
, search_mapped_to_caps_lock
);
1281 void UpdateEnterpriseDomain() {
1282 std::string enterprise_domain
=
1283 g_browser_process
->browser_policy_connector()->GetEnterpriseDomain();
1284 if (enterprise_domain_
!= enterprise_domain
) {
1285 enterprise_domain_
= enterprise_domain
;
1286 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1290 // Overridden from CloudPolicyStore::Observer
1291 virtual void OnStoreLoaded(policy::CloudPolicyStore
* store
) OVERRIDE
{
1292 UpdateEnterpriseDomain();
1295 virtual void OnStoreError(policy::CloudPolicyStore
* store
) OVERRIDE
{
1296 UpdateEnterpriseDomain();
1299 // Overridden from ash::SessionStateObserver
1300 virtual void ActiveUserChanged(const std::string
& user_id
) OVERRIDE
{
1301 GetSystemTrayNotifier()->NotifyUserUpdate();
1304 virtual void UserAddedToSession(const std::string
& user_id
) OVERRIDE
{
1305 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1308 scoped_ptr
<base::WeakPtrFactory
<SystemTrayDelegate
> > ui_weak_ptr_factory_
;
1309 scoped_ptr
<content::NotificationRegistrar
> registrar_
;
1310 scoped_ptr
<PrefChangeRegistrar
> local_state_registrar_
;
1311 scoped_ptr
<PrefChangeRegistrar
> user_pref_registrar_
;
1312 Profile
* user_profile_
;
1313 base::HourClockType clock_type_
;
1314 int search_key_mapped_to_
;
1315 bool screen_locked_
;
1316 bool have_session_start_time_
;
1317 base::TimeTicks session_start_time_
;
1318 bool have_session_length_limit_
;
1319 base::TimeDelta session_length_limit_
;
1320 std::string enterprise_domain_
;
1322 scoped_refptr
<device::BluetoothAdapter
> bluetooth_adapter_
;
1323 scoped_ptr
<ash::VolumeControlDelegate
> volume_control_delegate_
;
1325 DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegate
);
1330 ash::SystemTrayDelegate
* CreateSystemTrayDelegate() {
1331 return new chromeos::SystemTrayDelegate();
1334 } // namespace chromeos