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/ime/input_method_menu_item.h"
15 #include "ash/ime/input_method_menu_manager.h"
16 #include "ash/metrics/user_metrics_recorder.h"
17 #include "ash/session/session_state_delegate.h"
18 #include "ash/session/session_state_observer.h"
19 #include "ash/shell.h"
20 #include "ash/shell_delegate.h"
21 #include "ash/shell_window_ids.h"
22 #include "ash/system/bluetooth/bluetooth_observer.h"
23 #include "ash/system/chromeos/session/logout_button_observer.h"
24 #include "ash/system/date/clock_observer.h"
25 #include "ash/system/drive/drive_observer.h"
26 #include "ash/system/ime/ime_observer.h"
27 #include "ash/system/tray/system_tray.h"
28 #include "ash/system/tray/system_tray_delegate.h"
29 #include "ash/system/tray/system_tray_notifier.h"
30 #include "ash/system/tray_accessibility.h"
31 #include "ash/system/user/login_status.h"
32 #include "ash/system/user/update_observer.h"
33 #include "ash/system/user/user_observer.h"
34 #include "ash/volume_control_delegate.h"
35 #include "ash/wm/lock_state_controller.h"
36 #include "base/bind_helpers.h"
37 #include "base/callback.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/drive/drive_integration_service.h"
52 #include "chrome/browser/chromeos/drive/job_list.h"
53 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
54 #include "chrome/browser/chromeos/events/system_key_event_listener.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/supervised_user_manager.h"
62 #include "chrome/browser/chromeos/login/user.h"
63 #include "chrome/browser/chromeos/login/user_adding_screen.h"
64 #include "chrome/browser/chromeos/login/user_manager.h"
65 #include "chrome/browser/chromeos/net/network_portal_detector.h"
66 #include "chrome/browser/chromeos/options/network_config_view.h"
67 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
68 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
69 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
70 #include "chrome/browser/chromeos/set_time_dialog.h"
71 #include "chrome/browser/chromeos/settings/cros_settings.h"
72 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
73 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
74 #include "chrome/browser/drive/drive_service_interface.h"
75 #include "chrome/browser/feedback/tracing_manager.h"
76 #include "chrome/browser/google/google_util.h"
77 #include "chrome/browser/lifetime/application_lifetime.h"
78 #include "chrome/browser/profiles/profile_manager.h"
79 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
80 #include "chrome/browser/ui/ash/stub_user_accounts_delegate.h"
81 #include "chrome/browser/ui/ash/volume_controller_chromeos.h"
82 #include "chrome/browser/ui/browser.h"
83 #include "chrome/browser/ui/browser_finder.h"
84 #include "chrome/browser/ui/browser_list.h"
85 #include "chrome/browser/ui/chrome_pages.h"
86 #include "chrome/browser/ui/host_desktop.h"
87 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
88 #include "chrome/browser/ui/singleton_tabs.h"
89 #include "chrome/browser/ui/tabs/tab_strip_model.h"
90 #include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h"
91 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
92 #include "chrome/browser/upgrade_detector.h"
93 #include "chrome/common/chrome_switches.h"
94 #include "chrome/common/pref_names.h"
95 #include "chrome/common/url_constants.h"
96 #include "chromeos/dbus/dbus_thread_manager.h"
97 #include "chromeos/dbus/session_manager_client.h"
98 #include "chromeos/ime/extension_ime_util.h"
99 #include "chromeos/ime/ime_keyboard.h"
100 #include "chromeos/ime/input_method_manager.h"
101 #include "chromeos/login/login_state.h"
102 #include "components/policy/core/common/cloud/cloud_policy_store.h"
103 #include "content/public/browser/notification_observer.h"
104 #include "content/public/browser/notification_service.h"
105 #include "content/public/browser/user_metrics.h"
106 #include "content/public/browser/web_contents.h"
107 #include "device/bluetooth/bluetooth_adapter.h"
108 #include "device/bluetooth/bluetooth_adapter_factory.h"
109 #include "device/bluetooth/bluetooth_device.h"
110 #include "grit/ash_strings.h"
111 #include "grit/generated_resources.h"
112 #include "grit/locale_settings.h"
113 #include "net/base/escape.h"
114 #include "third_party/cros_system_api/dbus/service_constants.h"
115 #include "ui/base/l10n/l10n_util.h"
116 #include "ui/base/l10n/time_format.h"
118 using drive::DriveIntegrationService
;
119 using drive::DriveIntegrationServiceFactory
;
125 // The minimum session length limit that can be set.
126 const int kSessionLengthLimitMinMs
= 30 * 1000; // 30 seconds.
128 // The maximum session length limit that can be set.
129 const int kSessionLengthLimitMaxMs
= 24 * 60 * 60 * 1000; // 24 hours.
131 const char kDisplaySettingsSubPageName
[] = "display";
132 const char kDisplayOverscanSettingsSubPageName
[] = "displayOverscan";
134 // The URL for the Google Drive settings page.
135 const char kDriveSettingsPageURL
[] = "https://drive.google.com";
137 void ExtractIMEInfo(const input_method::InputMethodDescriptor
& ime
,
138 const input_method::InputMethodUtil
& util
,
139 ash::IMEInfo
* info
) {
141 info
->name
= util
.GetInputMethodLongName(ime
);
142 info
->medium_name
= util
.GetInputMethodMediumName(ime
);
143 info
->short_name
= util
.GetInputMethodShortName(ime
);
144 info
->third_party
= extension_ime_util::IsExtensionIME(ime
.id());
147 gfx::NativeWindow
GetNativeWindowByStatus(ash::user::LoginStatus login_status
,
148 bool session_started
) {
150 (!session_started
|| login_status
== ash::user::LOGGED_IN_NONE
||
151 login_status
== ash::user::LOGGED_IN_LOCKED
)
152 ? ash::kShellWindowId_LockSystemModalContainer
153 : ash::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 void ShowSettingsSubPageForActiveUser(const std::string
& sub_page
) {
224 chrome::ShowSettingsSubPageForProfile(
225 ProfileManager::GetActiveUserProfile(), sub_page
);
228 void ShowNetworkSettingsPage(const std::string
& service_path
) {
229 std::string page
= chrome::kInternetOptionsSubPage
;
230 page
+= "?servicePath=" + net::EscapeUrlEncodedData(service_path
, true);
231 content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog"));
232 ShowSettingsSubPageForActiveUser(page
);
235 void OnAcceptMultiprofilesIntro(bool no_show_again
) {
236 PrefService
* prefs
= ProfileManager::GetActiveUserProfile()->GetPrefs();
237 prefs
->SetBoolean(prefs::kMultiProfileNeverShowIntro
, no_show_again
);
238 UserAddingScreen::Get()->Start();
243 SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
244 : weak_ptr_factory_(this),
246 clock_type_(base::GetHourClockType()),
247 search_key_mapped_to_(input_method::kSearchKey
),
248 screen_locked_(false),
249 have_session_start_time_(false),
250 have_session_length_limit_(false),
251 should_run_bluetooth_discovery_(false),
252 volume_control_delegate_(new VolumeController()),
253 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
254 kSystemUse24HourClock
,
255 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType
,
256 base::Unretained(this)))) {
257 // Register notifications on construction so that events such as
258 // PROFILE_CREATED do not get missed if they happen before Initialize().
259 registrar_
.reset(new content::NotificationRegistrar
);
260 registrar_
->Add(this,
261 chrome::NOTIFICATION_UPGRADE_RECOMMENDED
,
262 content::NotificationService::AllSources());
263 registrar_
->Add(this,
264 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
,
265 content::NotificationService::AllSources());
266 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE
) {
267 registrar_
->Add(this,
268 chrome::NOTIFICATION_SESSION_STARTED
,
269 content::NotificationService::AllSources());
271 registrar_
->Add(this,
272 chrome::NOTIFICATION_PROFILE_CREATED
,
273 content::NotificationService::AllSources());
274 registrar_
->Add(this,
275 chrome::NOTIFICATION_PROFILE_DESTROYED
,
276 content::NotificationService::AllSources());
278 AccessibilityManager
* accessibility_manager
= AccessibilityManager::Get();
279 CHECK(accessibility_manager
);
280 accessibility_subscription_
= accessibility_manager
->RegisterCallback(
281 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged
,
282 base::Unretained(this)));
285 void SystemTrayDelegateChromeOS::Initialize() {
286 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
288 input_method::InputMethodManager::Get()->AddObserver(this);
289 ash::ime::InputMethodMenuManager::GetInstance()->AddObserver(this);
292 device::BluetoothAdapterFactory::GetAdapter(
293 base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady
,
294 weak_ptr_factory_
.GetWeakPtr()));
296 ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(
299 if (LoginState::IsInitialized())
300 LoginState::Get()->AddObserver(this);
302 if (CrasAudioHandler::IsInitialized())
303 CrasAudioHandler::Get()->AddAudioObserver(this);
305 BrowserList::AddObserver(this);
308 void SystemTrayDelegateChromeOS::Shutdown() {
309 device_settings_observer_
.reset();
312 void SystemTrayDelegateChromeOS::InitializeOnAdapterReady(
313 scoped_refptr
<device::BluetoothAdapter
> adapter
) {
314 bluetooth_adapter_
= adapter
;
315 CHECK(bluetooth_adapter_
.get());
316 bluetooth_adapter_
->AddObserver(this);
318 local_state_registrar_
.reset(new PrefChangeRegistrar
);
319 local_state_registrar_
->Init(g_browser_process
->local_state());
321 UpdateSessionStartTime();
322 UpdateSessionLengthLimit();
324 local_state_registrar_
->Add(
325 prefs::kSessionStartTime
,
326 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime
,
327 base::Unretained(this)));
328 local_state_registrar_
->Add(
329 prefs::kSessionLengthLimit
,
330 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit
,
331 base::Unretained(this)));
333 policy::BrowserPolicyConnectorChromeOS
* policy_connector
=
334 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
335 policy::DeviceCloudPolicyManagerChromeOS
* policy_manager
=
336 policy_connector
->GetDeviceCloudPolicyManager();
338 policy_manager
->core()->store()->AddObserver(this);
339 UpdateEnterpriseDomain();
342 SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() {
343 // Unregister PrefChangeRegistrars.
344 local_state_registrar_
.reset();
345 user_pref_registrar_
.reset();
347 // Unregister content notifications before destroying any components.
350 // Unregister a11y status subscription.
351 accessibility_subscription_
.reset();
353 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
354 input_method::InputMethodManager::Get()->RemoveObserver(this);
355 ash::ime::InputMethodMenuManager::GetInstance()->RemoveObserver(this);
356 bluetooth_adapter_
->RemoveObserver(this);
357 ash::Shell::GetInstance()
358 ->session_state_delegate()
359 ->RemoveSessionStateObserver(this);
360 LoginState::Get()->RemoveObserver(this);
362 if (CrasAudioHandler::IsInitialized())
363 CrasAudioHandler::Get()->RemoveAudioObserver(this);
365 BrowserList::RemoveObserver(this);
366 StopObservingAppWindowRegistry();
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 void SystemTrayDelegateChromeOS::ChangeProfilePicture() {
419 content::RecordAction(
420 base::UserMetricsAction("OpenChangeProfilePictureDialog"));
421 ShowSettingsSubPageForActiveUser(chrome::kChangeProfilePictureSubPage
);
424 const std::string
SystemTrayDelegateChromeOS::GetEnterpriseDomain() const {
425 return enterprise_domain_
;
428 const base::string16
SystemTrayDelegateChromeOS::GetEnterpriseMessage() const {
429 if (GetEnterpriseDomain().empty())
430 return base::string16();
431 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE
,
432 base::UTF8ToUTF16(GetEnterpriseDomain()));
435 const std::string
SystemTrayDelegateChromeOS::GetLocallyManagedUserManager()
437 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
438 return std::string();
439 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayEmail(
440 chromeos::UserManager::Get()->GetActiveUser()->email());
444 SystemTrayDelegateChromeOS::GetLocallyManagedUserManagerName() const {
445 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
446 return base::string16();
447 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayName(
448 chromeos::UserManager::Get()->GetActiveUser()->email());
451 const base::string16
SystemTrayDelegateChromeOS::GetLocallyManagedUserMessage()
453 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED
)
454 return base::string16();
455 return l10n_util::GetStringFUTF16(
456 IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE
,
457 base::UTF8ToUTF16(GetLocallyManagedUserManager()));
460 bool SystemTrayDelegateChromeOS::SystemShouldUpgrade() const {
461 return UpgradeDetector::GetInstance()->notify_upgrade();
464 base::HourClockType
SystemTrayDelegateChromeOS::GetHourClockType() const {
468 void SystemTrayDelegateChromeOS::ShowSettings() {
469 ShowSettingsSubPageForActiveUser("");
472 bool SystemTrayDelegateChromeOS::ShouldShowSettings() {
473 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings();
476 void SystemTrayDelegateChromeOS::ShowDateSettings() {
477 content::RecordAction(base::UserMetricsAction("ShowDateOptions"));
478 std::string sub_page
=
479 std::string(chrome::kSearchSubPage
) + "#" +
480 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME
);
481 // Everybody can change the time zone (even though it is a device setting).
482 ShowSettingsSubPageForActiveUser(sub_page
);
485 void SystemTrayDelegateChromeOS::ShowSetTimeDialog() {
486 SetTimeDialog::ShowDialog(GetNativeWindow());
489 void SystemTrayDelegateChromeOS::ShowNetworkSettings(
490 const std::string
& service_path
) {
491 if (!LoginState::Get()->IsUserLoggedIn())
493 ShowNetworkSettingsPage(service_path
);
496 void SystemTrayDelegateChromeOS::ShowBluetoothSettings() {
497 // TODO(sad): Make this work.
500 void SystemTrayDelegateChromeOS::ShowDisplaySettings() {
501 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions"));
502 ShowSettingsSubPageForActiveUser(kDisplaySettingsSubPageName
);
505 void SystemTrayDelegateChromeOS::ShowChromeSlow() {
506 chrome::ScopedTabbedBrowserDisplayer
displayer(
507 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH
);
508 chrome::ShowSlow(displayer
.browser());
511 bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() {
512 // Packaged app is not counted as 'last active', so if a browser opening the
513 // display settings is in background of a packaged app, it will return true.
514 // TODO(mukai): fix this.
515 Browser
* active_browser
=
516 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH
);
520 content::WebContents
* active_contents
=
521 active_browser
->tab_strip_model()->GetActiveWebContents();
522 if (!active_contents
)
525 GURL visible_url
= active_contents
->GetLastCommittedURL();
526 GURL display_settings_url
=
527 chrome::GetSettingsUrl(kDisplaySettingsSubPageName
);
528 GURL display_overscan_url
=
529 chrome::GetSettingsUrl(kDisplayOverscanSettingsSubPageName
);
530 return (visible_url
!= display_settings_url
&&
531 visible_url
!= display_overscan_url
);
534 void SystemTrayDelegateChromeOS::ShowDriveSettings() {
535 // TODO(tengs): Open the drive-specific settings page once we put it in.
536 // For now just show Google Drive main page.
537 chrome::ScopedTabbedBrowserDisplayer
displayer(
538 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH
);
539 chrome::ShowSingletonTabOverwritingNTP(
541 chrome::GetSingletonTabNavigateParams(displayer
.browser(),
542 GURL(kDriveSettingsPageURL
)));
545 void SystemTrayDelegateChromeOS::ShowIMESettings() {
546 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog"));
547 ShowSettingsSubPageForActiveUser(chrome::kLanguageOptionsSubPage
);
550 void SystemTrayDelegateChromeOS::ShowHelp() {
551 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(),
552 chrome::HOST_DESKTOP_TYPE_ASH
,
553 chrome::HELP_SOURCE_MENU
);
556 void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() {
557 chrome::ScopedTabbedBrowserDisplayer
displayer(
558 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH
);
559 accessibility::ShowAccessibilityHelp(displayer
.browser());
562 void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() {
563 content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings"));
564 std::string sub_page
= std::string(chrome::kSearchSubPage
) + "#" +
565 l10n_util::GetStringUTF8(
566 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY
);
567 ShowSettingsSubPageForActiveUser(sub_page
);
570 void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() {
571 chrome::ScopedTabbedBrowserDisplayer
displayer(
572 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH
);
573 chrome::ShowPolicy(displayer
.browser());
576 void SystemTrayDelegateChromeOS::ShowLocallyManagedUserInfo() {
577 // TODO(antrim): find out what should we show in this case.
578 // http://crbug.com/229762
581 void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() {
582 ash::user::LoginStatus status
= GetUserLoginStatus();
583 if (status
== ash::user::LOGGED_IN_NONE
||
584 status
== ash::user::LOGGED_IN_LOCKED
) {
585 scoped_refptr
<chromeos::HelpAppLauncher
> help_app(
586 new chromeos::HelpAppLauncher(GetNativeWindow()));
587 help_app
->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE
);
589 GURL
url(google_util::StringAppendGoogleLocaleParam(
590 chrome::kLearnMoreEnterpriseURL
));
591 chrome::ScopedTabbedBrowserDisplayer
displayer(
592 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH
);
593 chrome::ShowSingletonTab(displayer
.browser(), url
);
597 void SystemTrayDelegateChromeOS::ShowUserLogin() {
598 ash::Shell
* shell
= ash::Shell::GetInstance();
599 if (!shell
->delegate()->IsMultiProfilesEnabled())
602 // Only regular users could add other users to current session.
603 if (UserManager::Get()->GetActiveUser()->GetType() !=
604 User::USER_TYPE_REGULAR
) {
608 if (static_cast<int>(UserManager::Get()->GetLoggedInUsers().size()) >=
609 shell
->session_state_delegate()->GetMaximumNumberOfLoggedInUsers())
612 // Launch sign in screen to add another user to current session.
613 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) {
614 // Don't show dialog if any logged in user in multi-profiles session
616 bool show_intro
= true;
617 const UserList logged_in_users
= UserManager::Get()->GetLoggedInUsers();
618 for (UserList::const_iterator it
= logged_in_users
.begin();
619 it
!= logged_in_users
.end();
621 show_intro
&= !multi_user_util::GetProfileFromUserID(
622 multi_user_util::GetUserIDFromEmail((*it
)->email()))
624 ->GetBoolean(prefs::kMultiProfileNeverShowIntro
);
629 base::Callback
<void(bool)> on_accept
=
630 base::Bind(&OnAcceptMultiprofilesIntro
);
631 ShowMultiprofilesIntroDialog(on_accept
);
633 UserAddingScreen::Get()->Start();
638 bool SystemTrayDelegateChromeOS::ShowSpringChargerReplacementDialog() {
639 if (!ChargerReplacementDialog::ShouldShowDialog())
642 ChargerReplacementDialog
* dialog
=
643 new ChargerReplacementDialog(GetNativeWindow());
648 bool SystemTrayDelegateChromeOS::IsSpringChargerReplacementDialogVisible() {
649 return ChargerReplacementDialog::IsDialogVisible();
652 bool SystemTrayDelegateChromeOS::HasUserConfirmedSafeSpringCharger() {
653 return ChargerReplacementHandler::GetChargerStatusPref() ==
654 ChargerReplacementHandler::CONFIRM_SAFE_CHARGER
;
657 void SystemTrayDelegateChromeOS::ShutDown() {
658 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
661 void SystemTrayDelegateChromeOS::SignOut() {
662 chrome::AttemptUserExit();
665 void SystemTrayDelegateChromeOS::RequestLockScreen() {
666 // TODO(antrim) : additional logging for crbug/173178
667 LOG(WARNING
) << "Requesting screen lock from AshSystemTrayDelegate";
668 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
671 void SystemTrayDelegateChromeOS::RequestRestartForUpdate() {
672 // We expect that UpdateEngine is in "Reboot for update" state now.
673 chrome::NotifyAndTerminate(true /* fast path */);
676 void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices(
677 ash::BluetoothDeviceList
* list
) {
678 device::BluetoothAdapter::DeviceList devices
=
679 bluetooth_adapter_
->GetDevices();
680 for (size_t i
= 0; i
< devices
.size(); ++i
) {
681 device::BluetoothDevice
* device
= devices
[i
];
682 ash::BluetoothDeviceInfo info
;
683 info
.address
= device
->GetAddress();
684 info
.display_name
= device
->GetName();
685 info
.connected
= device
->IsConnected();
686 info
.connecting
= device
->IsConnecting();
687 info
.paired
= device
->IsPaired();
688 list
->push_back(info
);
692 void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() {
693 if (GetBluetoothDiscovering()) {
694 LOG(WARNING
) << "Already have active Bluetooth device discovery session.";
697 VLOG(1) << "Requesting new Bluetooth device discovery session.";
698 should_run_bluetooth_discovery_
= true;
699 bluetooth_adapter_
->StartDiscoverySession(
700 base::Bind(&SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession
,
701 weak_ptr_factory_
.GetWeakPtr()),
702 base::Bind(&BluetoothSetDiscoveringError
));
705 void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() {
706 should_run_bluetooth_discovery_
= false;
707 if (!GetBluetoothDiscovering()) {
708 LOG(WARNING
) << "No active Bluetooth device discovery session.";
711 VLOG(1) << "Stopping Bluetooth device discovery session.";
712 bluetooth_discovery_session_
->Stop(
713 base::Bind(&base::DoNothing
), base::Bind(&BluetoothSetDiscoveringError
));
716 void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice(
717 const std::string
& address
) {
718 device::BluetoothDevice
* device
= bluetooth_adapter_
->GetDevice(address
);
719 if (!device
|| device
->IsConnecting() ||
720 (device
->IsConnected() && device
->IsPaired())) {
723 if (device
->IsPaired() && !device
->IsConnectable())
725 if (device
->IsPaired() || !device
->IsPairable()) {
726 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
727 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE
);
728 device
->Connect(NULL
,
729 base::Bind(&base::DoNothing
),
730 base::Bind(&BluetoothDeviceConnectError
));
731 } else { // Show paring dialog for the unpaired device.
732 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
733 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE
);
734 BluetoothPairingDialog
* dialog
=
735 new BluetoothPairingDialog(GetNativeWindow(), device
);
736 // The dialog deletes itself on close.
741 bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() {
742 return bluetooth_adapter_
->IsDiscovering();
745 void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo
* info
) {
746 input_method::InputMethodManager
* manager
=
747 input_method::InputMethodManager::Get();
748 input_method::InputMethodUtil
* util
= manager
->GetInputMethodUtil();
749 input_method::InputMethodDescriptor ime
= manager
->GetCurrentInputMethod();
750 ExtractIMEInfo(ime
, *util
, info
);
751 info
->selected
= true;
754 void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList
* list
) {
755 input_method::InputMethodManager
* manager
=
756 input_method::InputMethodManager::Get();
757 input_method::InputMethodUtil
* util
= manager
->GetInputMethodUtil();
758 scoped_ptr
<input_method::InputMethodDescriptors
> ime_descriptors(
759 manager
->GetActiveInputMethods());
760 std::string current
= manager
->GetCurrentInputMethod().id();
761 for (size_t i
= 0; i
< ime_descriptors
->size(); i
++) {
762 input_method::InputMethodDescriptor
& ime
= ime_descriptors
->at(i
);
764 ExtractIMEInfo(ime
, *util
, &info
);
765 info
.selected
= ime
.id() == current
;
766 list
->push_back(info
);
770 void SystemTrayDelegateChromeOS::GetCurrentIMEProperties(
771 ash::IMEPropertyInfoList
* list
) {
772 ash::ime::InputMethodMenuItemList menu_list
=
773 ash::ime::InputMethodMenuManager::GetInstance()->
774 GetCurrentInputMethodMenuItemList();
775 for (size_t i
= 0; i
< menu_list
.size(); ++i
) {
776 ash::IMEPropertyInfo property
;
777 property
.key
= menu_list
[i
].key
;
778 property
.name
= base::UTF8ToUTF16(menu_list
[i
].label
);
779 property
.selected
= menu_list
[i
].is_selection_item_checked
;
780 list
->push_back(property
);
784 void SystemTrayDelegateChromeOS::SwitchIME(const std::string
& ime_id
) {
785 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id
);
788 void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string
& key
) {
789 input_method::InputMethodManager::Get()->ActivateInputMethodMenuItem(key
);
792 void SystemTrayDelegateChromeOS::CancelDriveOperation(int32 operation_id
) {
793 DriveIntegrationService
* integration_service
= FindDriveIntegrationService();
794 if (!integration_service
)
797 integration_service
->job_list()->CancelJob(operation_id
);
800 void SystemTrayDelegateChromeOS::GetDriveOperationStatusList(
801 ash::DriveOperationStatusList
* list
) {
802 DriveIntegrationService
* integration_service
= FindDriveIntegrationService();
803 if (!integration_service
)
806 *list
= ConvertToDriveStatusList(
807 integration_service
->job_list()->GetJobInfoList());
810 void SystemTrayDelegateChromeOS::ShowNetworkConfigure(
811 const std::string
& network_id
,
812 gfx::NativeWindow parent_window
) {
813 NetworkConfigView::Show(network_id
, parent_window
);
816 bool SystemTrayDelegateChromeOS::EnrollNetwork(
817 const std::string
& network_id
,
818 gfx::NativeWindow parent_window
) {
819 return enrollment::CreateDialog(network_id
, parent_window
);
822 void SystemTrayDelegateChromeOS::ManageBluetoothDevices() {
823 content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage"));
824 std::string sub_page
=
825 std::string(chrome::kSearchSubPage
) + "#" +
826 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH
);
827 ShowSettingsSubPageForActiveUser(sub_page
);
830 void SystemTrayDelegateChromeOS::ToggleBluetooth() {
831 bluetooth_adapter_
->SetPowered(!bluetooth_adapter_
->IsPowered(),
832 base::Bind(&base::DoNothing
),
833 base::Bind(&BluetoothPowerFailure
));
836 void SystemTrayDelegateChromeOS::ShowMobileSimDialog() {
837 SimDialogDelegate::ShowDialog(GetNativeWindow(),
838 SimDialogDelegate::SIM_DIALOG_UNLOCK
);
841 void SystemTrayDelegateChromeOS::ShowMobileSetupDialog(
842 const std::string
& service_path
) {
843 MobileSetupDialog::Show(service_path
);
846 void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog(
847 const std::string
& type
) {
848 if (type
== shill::kTypeCellular
) {
849 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
852 NetworkConfigView::ShowForType(type
, GetNativeWindow());
855 bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() {
856 return bluetooth_adapter_
->IsPresent();
859 bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() {
860 return bluetooth_adapter_
->IsPowered();
863 bool SystemTrayDelegateChromeOS::GetBluetoothDiscovering() {
864 return (bluetooth_discovery_session_
.get() &&
865 bluetooth_discovery_session_
->IsActive());
868 void SystemTrayDelegateChromeOS::ChangeProxySettings() {
869 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE
);
870 LoginDisplayHostImpl::default_host()->OpenProxySettings();
873 ash::VolumeControlDelegate
*
874 SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const {
875 return volume_control_delegate_
.get();
878 void SystemTrayDelegateChromeOS::SetVolumeControlDelegate(
879 scoped_ptr
<ash::VolumeControlDelegate
> delegate
) {
880 volume_control_delegate_
.swap(delegate
);
883 bool SystemTrayDelegateChromeOS::GetSessionStartTime(
884 base::TimeTicks
* session_start_time
) {
885 *session_start_time
= session_start_time_
;
886 return have_session_start_time_
;
889 bool SystemTrayDelegateChromeOS::GetSessionLengthLimit(
890 base::TimeDelta
* session_length_limit
) {
891 *session_length_limit
= session_length_limit_
;
892 return have_session_length_limit_
;
895 int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() {
896 return l10n_util::GetLocalizedContentsWidthInPixels(
897 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS
);
900 void SystemTrayDelegateChromeOS::ActiveUserWasChanged() {
901 GetSystemTrayNotifier()->NotifyUserUpdate();
904 bool SystemTrayDelegateChromeOS::IsNetworkBehindCaptivePortal(
905 const std::string
& service_path
) const {
906 NetworkPortalDetector::CaptivePortalState state
=
907 NetworkPortalDetector::Get()->GetCaptivePortalState(service_path
);
908 return state
.status
== NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
911 bool SystemTrayDelegateChromeOS::IsSearchKeyMappedToCapsLock() {
912 return search_key_mapped_to_
== input_method::kCapsLockKey
;
915 ash::tray::UserAccountsDelegate
*
916 SystemTrayDelegateChromeOS::GetUserAccountsDelegate(
917 const std::string
& user_id
) {
918 if (!accounts_delegates_
.contains(user_id
)) {
919 // TODO(dzhioev): replace stub with real implementation.
920 accounts_delegates_
.set(user_id
,
921 scoped_ptr
<ash::tray::UserAccountsDelegate
>(
922 new StubUserAccountsDelegate(user_id
)));
923 static_cast<StubUserAccountsDelegate
*>(accounts_delegates_
.get(user_id
))
924 ->AddAccount("secondary_account1@gmail.com");
925 static_cast<StubUserAccountsDelegate
*>(accounts_delegates_
.get(user_id
))
926 ->AddAccount("very_long_account_name_for_user@gmail.com");
927 static_cast<StubUserAccountsDelegate
*>(accounts_delegates_
.get(user_id
))
928 ->AddAccount("secondary_account2@gmail.com");
929 static_cast<StubUserAccountsDelegate
*>(accounts_delegates_
.get(user_id
))
930 ->AddAccount("very_very_very_long_account_name_for_user@gmail.com");
932 return accounts_delegates_
.get(user_id
);
935 ash::SystemTray
* SystemTrayDelegateChromeOS::GetPrimarySystemTray() {
936 return ash::Shell::GetInstance()->GetPrimarySystemTray();
939 ash::SystemTrayNotifier
* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() {
940 return ash::Shell::GetInstance()->system_tray_notifier();
943 void SystemTrayDelegateChromeOS::SetProfile(Profile
* profile
) {
944 // Stop observing the Drive integration status and the AppWindowRegistry of
945 // the current |user_profile_|.
946 UnobserveDriveUpdates();
947 StopObservingAppWindowRegistry();
949 user_profile_
= profile
;
951 // Start observing the Drive integration status and the AppWindowRegistry of
952 // the newly set |user_profile_|.
953 ObserveDriveUpdates();
954 apps::AppWindowRegistry::Get(user_profile_
)->AddObserver(this);
956 PrefService
* prefs
= profile
->GetPrefs();
957 user_pref_registrar_
.reset(new PrefChangeRegistrar
);
958 user_pref_registrar_
->Init(prefs
);
959 user_pref_registrar_
->Add(
960 prefs::kUse24HourClock
,
961 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType
,
962 base::Unretained(this)));
963 user_pref_registrar_
->Add(
964 prefs::kLanguageRemapSearchKeyTo
,
965 base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged
,
966 base::Unretained(this)));
967 user_pref_registrar_
->Add(
968 prefs::kShowLogoutButtonInTray
,
969 base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray
,
970 base::Unretained(this)));
971 user_pref_registrar_
->Add(
972 prefs::kLogoutDialogDurationMs
,
973 base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration
,
974 base::Unretained(this)));
975 user_pref_registrar_
->Add(
976 prefs::kLargeCursorEnabled
,
977 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged
,
978 base::Unretained(this),
979 ash::A11Y_NOTIFICATION_NONE
));
980 user_pref_registrar_
->Add(
981 prefs::kAutoclickEnabled
,
982 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged
,
983 base::Unretained(this),
984 ash::A11Y_NOTIFICATION_NONE
));
985 user_pref_registrar_
->Add(
986 prefs::kShouldAlwaysShowAccessibilityMenu
,
987 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged
,
988 base::Unretained(this),
989 ash::A11Y_NOTIFICATION_NONE
));
990 user_pref_registrar_
->Add(
991 prefs::kPerformanceTracingEnabled
,
992 base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing
,
993 base::Unretained(this)));
996 UpdateShowLogoutButtonInTray();
997 UpdateLogoutDialogDuration();
998 UpdatePerformanceTracing();
999 search_key_mapped_to_
=
1000 profile
->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo
);
1003 bool SystemTrayDelegateChromeOS::UnsetProfile(Profile
* profile
) {
1004 if (profile
!= user_profile_
)
1006 user_pref_registrar_
.reset();
1007 user_profile_
= NULL
;
1011 void SystemTrayDelegateChromeOS::ObserveDriveUpdates() {
1012 DriveIntegrationService
* integration_service
= FindDriveIntegrationService();
1013 if (integration_service
)
1014 integration_service
->job_list()->AddObserver(this);
1017 void SystemTrayDelegateChromeOS::UnobserveDriveUpdates() {
1018 DriveIntegrationService
* integration_service
= FindDriveIntegrationService();
1019 if (integration_service
)
1020 integration_service
->job_list()->RemoveObserver(this);
1023 bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const {
1024 return ShouldUse24HourClock();
1027 bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const {
1028 // On login screen and in guest mode owner default is used for
1029 // kUse24HourClock preference.
1030 const ash::user::LoginStatus status
= GetUserLoginStatus();
1031 const CrosSettings
* const cros_settings
= CrosSettings::Get();
1032 bool system_use_24_hour_clock
= true;
1033 const bool system_value_found
= cros_settings
->GetBoolean(
1034 kSystemUse24HourClock
, &system_use_24_hour_clock
);
1036 if ((status
== ash::user::LOGGED_IN_NONE
) || !user_pref_registrar_
)
1037 return (system_value_found
1038 ? system_use_24_hour_clock
1039 : (base::GetHourClockType() == base::k24HourClock
));
1041 const PrefService::Preference
* user_pref
=
1042 user_pref_registrar_
->prefs()->FindPreference(prefs::kUse24HourClock
);
1043 if (status
== ash::user::LOGGED_IN_GUEST
&& user_pref
->IsDefaultValue())
1044 return (system_value_found
1045 ? system_use_24_hour_clock
1046 : (base::GetHourClockType() == base::k24HourClock
));
1048 bool use_24_hour_clock
= true;
1049 user_pref
->GetValue()->GetAsBoolean(&use_24_hour_clock
);
1050 return use_24_hour_clock
;
1053 void SystemTrayDelegateChromeOS::UpdateClockType() {
1054 const bool use_24_hour_clock
= ShouldUse24HourClock();
1055 clock_type_
= use_24_hour_clock
? base::k24HourClock
: base::k12HourClock
;
1056 GetSystemTrayNotifier()->NotifyDateFormatChanged();
1057 // This also works for enterprise-managed devices because they never have
1059 if (chromeos::UserManager::Get()->IsCurrentUserOwner())
1060 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock
, use_24_hour_clock
);
1063 void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() {
1064 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
1065 user_pref_registrar_
->prefs()->GetBoolean(
1066 prefs::kShowLogoutButtonInTray
));
1069 void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() {
1070 const int duration_ms
=
1071 user_pref_registrar_
->prefs()->GetInteger(prefs::kLogoutDialogDurationMs
);
1072 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged(
1073 base::TimeDelta::FromMilliseconds(duration_ms
));
1076 void SystemTrayDelegateChromeOS::UpdateSessionStartTime() {
1077 const PrefService
* local_state
= local_state_registrar_
->prefs();
1078 if (local_state
->HasPrefPath(prefs::kSessionStartTime
)) {
1079 have_session_start_time_
= true;
1080 session_start_time_
= base::TimeTicks::FromInternalValue(
1081 local_state
->GetInt64(prefs::kSessionStartTime
));
1083 have_session_start_time_
= false;
1084 session_start_time_
= base::TimeTicks();
1086 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
1089 void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() {
1090 const PrefService
* local_state
= local_state_registrar_
->prefs();
1091 if (local_state
->HasPrefPath(prefs::kSessionLengthLimit
)) {
1092 have_session_length_limit_
= true;
1093 session_length_limit_
= base::TimeDelta::FromMilliseconds(
1094 std::min(std::max(local_state
->GetInteger(prefs::kSessionLengthLimit
),
1095 kSessionLengthLimitMinMs
),
1096 kSessionLengthLimitMaxMs
));
1098 have_session_length_limit_
= false;
1099 session_length_limit_
= base::TimeDelta();
1101 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
1104 void SystemTrayDelegateChromeOS::StopObservingAppWindowRegistry() {
1108 apps::AppWindowRegistry
* registry
=
1109 apps::AppWindowRegistry::Factory::GetForBrowserContext(user_profile_
,
1112 registry
->RemoveObserver(this);
1115 void SystemTrayDelegateChromeOS::NotifyIfLastWindowClosed() {
1119 BrowserList
* browser_list
=
1120 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH
);
1121 for (BrowserList::const_iterator it
= browser_list
->begin();
1122 it
!= browser_list
->end();
1124 if ((*it
)->profile()->IsSameProfile(user_profile_
)) {
1125 // The current user has at least one open browser window.
1130 if (!apps::AppWindowRegistry::Get(user_profile_
)->app_windows().empty()) {
1131 // The current user has at least one open app window.
1135 GetSystemTrayNotifier()->NotifyLastWindowClosed();
1138 // LoginState::Observer overrides.
1139 void SystemTrayDelegateChromeOS::LoggedInStateChanged() {
1140 // It apparently sometimes takes a while after login before the current user
1141 // is recognized as the owner. Make sure that the system-wide clock setting
1142 // is updated when the recognition eventually happens
1143 // (http://crbug.com/278601).
1145 // Note that it isn't safe to blindly call UpdateClockType() from this
1146 // method, as LoggedInStateChanged() is also called before the logged-in
1147 // user's profile has actually been loaded (http://crbug.com/317745). The
1148 // system tray's time format is updated at login via SetProfile().
1149 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) {
1150 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock
,
1151 ShouldUse24HourClock());
1155 // Overridden from SessionManagerClient::Observer.
1156 void SystemTrayDelegateChromeOS::ScreenIsLocked() {
1157 screen_locked_
= true;
1158 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1161 void SystemTrayDelegateChromeOS::ScreenIsUnlocked() {
1162 screen_locked_
= false;
1163 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1166 gfx::NativeWindow
SystemTrayDelegateChromeOS::GetNativeWindow() const {
1167 bool session_started
= ash::Shell::GetInstance()
1168 ->session_state_delegate()
1169 ->IsActiveUserSessionStarted();
1170 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started
);
1173 // content::NotificationObserver implementation.
1174 void SystemTrayDelegateChromeOS::Observe(
1176 const content::NotificationSource
& source
,
1177 const content::NotificationDetails
& details
) {
1179 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED
: {
1180 UpgradeDetector
* detector
=
1181 content::Source
<UpgradeDetector
>(source
).ptr();
1182 ash::UpdateObserver::UpdateSeverity severity
=
1183 ash::UpdateObserver::UPDATE_NORMAL
;
1184 switch (detector
->upgrade_notification_stage()) {
1185 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE
:
1186 severity
= ash::UpdateObserver::UPDATE_SEVERE_RED
;
1189 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH
:
1190 severity
= ash::UpdateObserver::UPDATE_HIGH_ORANGE
;
1193 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED
:
1194 severity
= ash::UpdateObserver::UPDATE_LOW_GREEN
;
1197 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW
:
1199 severity
= ash::UpdateObserver::UPDATE_NORMAL
;
1202 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity
);
1205 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
: {
1206 // This notification is also sent on login screen when user avatar
1207 // is loaded from file.
1208 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE
) {
1209 GetSystemTrayNotifier()->NotifyUserUpdate();
1213 case chrome::NOTIFICATION_PROFILE_CREATED
: {
1214 SetProfile(content::Source
<Profile
>(source
).ptr());
1215 registrar_
->Remove(this,
1216 chrome::NOTIFICATION_PROFILE_CREATED
,
1217 content::NotificationService::AllSources());
1220 case chrome::NOTIFICATION_PROFILE_DESTROYED
: {
1221 if (UnsetProfile(content::Source
<Profile
>(source
).ptr())) {
1222 registrar_
->Remove(this,
1223 chrome::NOTIFICATION_PROFILE_DESTROYED
,
1224 content::NotificationService::AllSources());
1228 case chrome::NOTIFICATION_SESSION_STARTED
: {
1229 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1230 GetUserLoginStatus());
1231 SetProfile(ProfileManager::GetActiveUserProfile());
1239 void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() {
1240 search_key_mapped_to_
= user_pref_registrar_
->prefs()->GetInteger(
1241 prefs::kLanguageRemapSearchKeyTo
);
1244 void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged(
1245 ash::AccessibilityNotificationVisibility notify
) {
1246 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify
);
1249 void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() {
1250 if (!user_pref_registrar_
)
1252 bool value
= user_pref_registrar_
->prefs()->GetBoolean(
1253 prefs::kPerformanceTracingEnabled
);
1254 GetSystemTrayNotifier()->NotifyTracingModeChanged(value
);
1257 // Overridden from InputMethodManager::Observer.
1258 void SystemTrayDelegateChromeOS::InputMethodChanged(
1259 input_method::InputMethodManager
* manager
,
1260 bool show_message
) {
1261 GetSystemTrayNotifier()->NotifyRefreshIME();
1264 // Overridden from InputMethodMenuManager::Observer.
1265 void SystemTrayDelegateChromeOS::InputMethodMenuItemChanged(
1266 ash::ime::InputMethodMenuManager
* manager
) {
1267 GetSystemTrayNotifier()->NotifyRefreshIME();
1270 // Overridden from CrasAudioHandler::AudioObserver.
1271 void SystemTrayDelegateChromeOS::OnOutputVolumeChanged() {
1272 GetSystemTrayNotifier()->NotifyAudioOutputVolumeChanged();
1275 void SystemTrayDelegateChromeOS::OnOutputMuteChanged() {
1276 GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged();
1279 void SystemTrayDelegateChromeOS::OnInputGainChanged() {
1282 void SystemTrayDelegateChromeOS::OnInputMuteChanged() {
1285 void SystemTrayDelegateChromeOS::OnAudioNodesChanged() {
1286 GetSystemTrayNotifier()->NotifyAudioNodesChanged();
1289 void SystemTrayDelegateChromeOS::OnActiveOutputNodeChanged() {
1290 GetSystemTrayNotifier()->NotifyAudioActiveOutputNodeChanged();
1293 void SystemTrayDelegateChromeOS::OnActiveInputNodeChanged() {
1294 GetSystemTrayNotifier()->NotifyAudioActiveInputNodeChanged();
1297 // drive::JobListObserver overrides.
1298 void SystemTrayDelegateChromeOS::OnJobAdded(const drive::JobInfo
& job_info
) {
1299 OnJobUpdated(job_info
);
1302 void SystemTrayDelegateChromeOS::OnJobDone(const drive::JobInfo
& job_info
,
1303 drive::FileError error
) {
1304 ash::DriveOperationStatus status
;
1305 if (ConvertToFinishedDriveOperationStatus(job_info
, error
, &status
))
1306 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status
);
1309 void SystemTrayDelegateChromeOS::OnJobUpdated(const drive::JobInfo
& job_info
) {
1310 ash::DriveOperationStatus status
;
1311 if (ConvertToDriveOperationStatus(job_info
, &status
))
1312 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status
);
1315 DriveIntegrationService
*
1316 SystemTrayDelegateChromeOS::FindDriveIntegrationService() {
1317 return user_profile_
1318 ? DriveIntegrationServiceFactory::FindForProfile(user_profile_
)
1322 // Overridden from BluetoothAdapter::Observer.
1323 void SystemTrayDelegateChromeOS::AdapterPresentChanged(
1324 device::BluetoothAdapter
* adapter
,
1326 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1329 void SystemTrayDelegateChromeOS::AdapterPoweredChanged(
1330 device::BluetoothAdapter
* adapter
,
1332 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1335 void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged(
1336 device::BluetoothAdapter
* adapter
,
1338 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1341 void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter
* adapter
,
1342 device::BluetoothDevice
* device
) {
1343 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1346 void SystemTrayDelegateChromeOS::DeviceChanged(
1347 device::BluetoothAdapter
* adapter
,
1348 device::BluetoothDevice
* device
) {
1349 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1352 void SystemTrayDelegateChromeOS::DeviceRemoved(
1353 device::BluetoothAdapter
* adapter
,
1354 device::BluetoothDevice
* device
) {
1355 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1358 void SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession(
1359 scoped_ptr
<device::BluetoothDiscoverySession
> discovery_session
) {
1360 // If the discovery session was returned after a request to stop discovery
1361 // (e.g. the user dismissed the Bluetooth detailed view before the call
1362 // returned), don't claim the discovery session and let it clean up.
1363 if (!should_run_bluetooth_discovery_
)
1365 VLOG(1) << "Claiming new Bluetooth device discovery session.";
1366 bluetooth_discovery_session_
= discovery_session
.Pass();
1367 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1370 void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() {
1371 policy::BrowserPolicyConnectorChromeOS
* connector
=
1372 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1373 std::string enterprise_domain
= connector
->GetEnterpriseDomain();
1374 if (enterprise_domain_
!= enterprise_domain
) {
1375 enterprise_domain_
= enterprise_domain
;
1376 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1380 // Overridden from CloudPolicyStore::Observer
1381 void SystemTrayDelegateChromeOS::OnStoreLoaded(
1382 policy::CloudPolicyStore
* store
) {
1383 UpdateEnterpriseDomain();
1386 void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore
* store
) {
1387 UpdateEnterpriseDomain();
1390 // Overridden from ash::SessionStateObserver
1391 void SystemTrayDelegateChromeOS::UserAddedToSession(
1392 const std::string
& user_id
) {
1393 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1396 // Overridden from chrome::BrowserListObserver.
1397 void SystemTrayDelegateChromeOS::OnBrowserRemoved(Browser
* browser
) {
1398 NotifyIfLastWindowClosed();
1401 // Overridden from apps::AppWindowRegistry::Observer.
1402 void SystemTrayDelegateChromeOS::OnAppWindowAdded(apps::AppWindow
* app_window
) {
1405 void SystemTrayDelegateChromeOS::OnAppWindowIconChanged(
1406 apps::AppWindow
* app_window
) {}
1408 void SystemTrayDelegateChromeOS::OnAppWindowRemoved(
1409 apps::AppWindow
* app_window
) {
1410 NotifyIfLastWindowClosed();
1413 void SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged(
1414 const AccessibilityStatusEventDetails
& details
) {
1415 if (details
.notification_type
== ACCESSIBILITY_MANAGER_SHUTDOWN
)
1416 accessibility_subscription_
.reset();
1418 OnAccessibilityModeChanged(details
.notify
);
1421 ash::SystemTrayDelegate
* CreateSystemTrayDelegate() {
1422 return new SystemTrayDelegateChromeOS();
1425 } // namespace chromeos