Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / ash / system_tray_delegate_chromeos.cc
blob2ec98cc72a4ec914f0bb5f43bc737ead422954fa
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"
7 #include <algorithm>
8 #include <set>
9 #include <string>
10 #include <vector>
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/session_state_delegate.h"
16 #include "ash/session/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/chromeos/session/logout_button_observer.h"
22 #include "ash/system/chromeos/shutdown_policy_observer.h"
23 #include "ash/system/date/clock_observer.h"
24 #include "ash/system/ime/ime_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/user/login_status.h"
30 #include "ash/system/user/update_observer.h"
31 #include "ash/system/user/user_observer.h"
32 #include "ash/volume_control_delegate.h"
33 #include "ash/wm/lock_state_controller.h"
34 #include "base/bind_helpers.h"
35 #include "base/callback.h"
36 #include "base/logging.h"
37 #include "base/memory/weak_ptr.h"
38 #include "base/prefs/pref_service.h"
39 #include "base/strings/stringprintf.h"
40 #include "base/strings/utf_string_conversions.h"
41 #include "base/sys_info.h"
42 #include "base/time/time.h"
43 #include "chrome/browser/browser_process.h"
44 #include "chrome/browser/chrome_notification_types.h"
45 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
46 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
47 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h"
48 #include "chrome/browser/chromeos/events/system_key_event_listener.h"
49 #include "chrome/browser/chromeos/input_method/input_method_switch_recorder.h"
50 #include "chrome/browser/chromeos/input_method/input_method_util.h"
51 #include "chrome/browser/chromeos/login/help_app_launcher.h"
52 #include "chrome/browser/chromeos/login/login_wizard.h"
53 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
54 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
55 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
56 #include "chrome/browser/chromeos/login/user_flow.h"
57 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
58 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
59 #include "chrome/browser/chromeos/options/network_config_view.h"
60 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
61 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
62 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
63 #include "chrome/browser/chromeos/profiles/profile_helper.h"
64 #include "chrome/browser/chromeos/set_time_dialog.h"
65 #include "chrome/browser/chromeos/settings/cros_settings.h"
66 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
67 #include "chrome/browser/lifetime/application_lifetime.h"
68 #include "chrome/browser/profiles/profile_manager.h"
69 #include "chrome/browser/supervised_user/supervised_user_service.h"
70 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
71 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
72 #include "chrome/browser/ui/ash/networking_config_delegate_chromeos.h"
73 #include "chrome/browser/ui/ash/system_tray_delegate_utils.h"
74 #include "chrome/browser/ui/ash/user_accounts_delegate_chromeos.h"
75 #include "chrome/browser/ui/ash/volume_controller_chromeos.h"
76 #include "chrome/browser/ui/ash/vpn_delegate_chromeos.h"
77 #include "chrome/browser/ui/browser.h"
78 #include "chrome/browser/ui/browser_finder.h"
79 #include "chrome/browser/ui/browser_list.h"
80 #include "chrome/browser/ui/chrome_pages.h"
81 #include "chrome/browser/ui/host_desktop.h"
82 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
83 #include "chrome/browser/ui/singleton_tabs.h"
84 #include "chrome/browser/ui/tabs/tab_strip_model.h"
85 #include "chrome/browser/upgrade_detector.h"
86 #include "chrome/common/chrome_switches.h"
87 #include "chrome/common/pref_names.h"
88 #include "chrome/common/url_constants.h"
89 #include "chrome/grit/generated_resources.h"
90 #include "chrome/grit/locale_settings.h"
91 #include "chromeos/dbus/dbus_thread_manager.h"
92 #include "chromeos/dbus/session_manager_client.h"
93 #include "chromeos/login/login_state.h"
94 #include "chromeos/network/portal_detector/network_portal_detector.h"
95 #include "components/google/core/browser/google_util.h"
96 #include "components/policy/core/common/cloud/cloud_policy_store.h"
97 #include "components/user_manager/user.h"
98 #include "components/user_manager/user_manager.h"
99 #include "components/user_manager/user_type.h"
100 #include "content/public/browser/notification_observer.h"
101 #include "content/public/browser/notification_service.h"
102 #include "content/public/browser/user_metrics.h"
103 #include "content/public/browser/web_contents.h"
104 #include "device/bluetooth/bluetooth_adapter.h"
105 #include "device/bluetooth/bluetooth_adapter_factory.h"
106 #include "device/bluetooth/bluetooth_device.h"
107 #include "net/base/escape.h"
108 #include "third_party/cros_system_api/dbus/service_constants.h"
109 #include "ui/base/ime/chromeos/extension_ime_util.h"
110 #include "ui/base/ime/chromeos/ime_keyboard.h"
111 #include "ui/base/ime/chromeos/input_method_manager.h"
112 #include "ui/base/l10n/l10n_util.h"
113 #include "ui/base/l10n/time_format.h"
114 #include "ui/chromeos/ime/input_method_menu_item.h"
115 #include "ui/chromeos/ime/input_method_menu_manager.h"
117 #if defined(ENABLE_SUPERVISED_USERS)
118 #include "chrome/browser/supervised_user/supervised_user_service.h"
119 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
120 #endif
122 namespace chromeos {
124 namespace {
126 // The minimum session length limit that can be set.
127 const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
129 // The maximum session length limit that can be set.
130 const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
132 const char kDisplaySettingsSubPageName[] = "display";
133 const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan";
135 void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
136 const input_method::InputMethodUtil& util,
137 ash::IMEInfo* info) {
138 info->id = ime.id();
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(ash::user::LoginStatus login_status,
146 bool session_started) {
147 bool isUserAddingRunning = ash::Shell::GetInstance()
148 ->session_state_delegate()
149 ->IsInSecondaryLoginScreen();
151 int container_id =
152 (!session_started || login_status == ash::user::LOGGED_IN_NONE ||
153 login_status == ash::user::LOGGED_IN_LOCKED || isUserAddingRunning)
154 ? ash::kShellWindowId_LockSystemModalContainer
155 : ash::kShellWindowId_SystemModalContainer;
156 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
157 container_id);
160 void BluetoothPowerFailure() {
161 // TODO(sad): Show an error bubble?
164 void BluetoothSetDiscoveringError() {
165 LOG(ERROR) << "BluetoothSetDiscovering failed.";
168 void BluetoothDeviceConnectError(
169 device::BluetoothDevice::ConnectErrorCode error_code) {
170 // TODO(sad): Do something?
173 void ShowSettingsSubPageForActiveUser(const std::string& sub_page) {
174 chrome::ShowSettingsSubPageForProfile(
175 ProfileManager::GetActiveUserProfile(), sub_page);
178 void OnAcceptMultiprofilesIntro(bool no_show_again) {
179 PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
180 prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again);
181 UserAddingScreen::Get()->Start();
184 } // namespace
186 SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
187 : user_profile_(NULL),
188 clock_type_(base::GetHourClockType()),
189 search_key_mapped_to_(input_method::kSearchKey),
190 screen_locked_(false),
191 have_session_start_time_(false),
192 have_session_length_limit_(false),
193 should_run_bluetooth_discovery_(false),
194 session_started_(false),
195 networking_config_delegate_(new NetworkingConfigDelegateChromeos()),
196 volume_control_delegate_(new VolumeController()),
197 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
198 kSystemUse24HourClock,
199 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
200 base::Unretained(this)))),
201 vpn_delegate_(new VPNDelegateChromeOS),
202 weak_ptr_factory_(this) {
203 // Register notifications on construction so that events such as
204 // PROFILE_CREATED do not get missed if they happen before Initialize().
205 registrar_.reset(new content::NotificationRegistrar);
206 registrar_->Add(this,
207 chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
208 content::NotificationService::AllSources());
209 registrar_->Add(this,
210 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
211 content::NotificationService::AllSources());
212 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) {
213 registrar_->Add(this,
214 chrome::NOTIFICATION_SESSION_STARTED,
215 content::NotificationService::AllSources());
217 registrar_->Add(this,
218 chrome::NOTIFICATION_PROFILE_CREATED,
219 content::NotificationService::AllSources());
220 registrar_->Add(this,
221 chrome::NOTIFICATION_PROFILE_DESTROYED,
222 content::NotificationService::AllSources());
223 registrar_->Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
224 content::NotificationService::AllSources());
226 AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
227 CHECK(accessibility_manager);
228 accessibility_subscription_ = accessibility_manager->RegisterCallback(
229 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged,
230 base::Unretained(this)));
232 user_manager::UserManager::Get()->AddSessionStateObserver(this);
233 shutdown_policy_handler_.reset(
234 new ShutdownPolicyHandler(CrosSettings::Get(), this));
237 void SystemTrayDelegateChromeOS::Initialize() {
238 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
240 input_method::InputMethodManager::Get()->AddObserver(this);
241 ui::ime::InputMethodMenuManager::GetInstance()->AddObserver(this);
242 UpdateClockType();
244 device::BluetoothAdapterFactory::GetAdapter(
245 base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady,
246 weak_ptr_factory_.GetWeakPtr()));
248 ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(
249 this);
251 if (LoginState::IsInitialized())
252 LoginState::Get()->AddObserver(this);
254 if (CrasAudioHandler::IsInitialized())
255 CrasAudioHandler::Get()->AddAudioObserver(this);
257 BrowserList::AddObserver(this);
260 void SystemTrayDelegateChromeOS::Shutdown() {
261 device_settings_observer_.reset();
264 void SystemTrayDelegateChromeOS::InitializeOnAdapterReady(
265 scoped_refptr<device::BluetoothAdapter> adapter) {
266 bluetooth_adapter_ = adapter;
267 CHECK(bluetooth_adapter_.get());
268 bluetooth_adapter_->AddObserver(this);
270 local_state_registrar_.reset(new PrefChangeRegistrar);
271 local_state_registrar_->Init(g_browser_process->local_state());
273 UpdateSessionStartTime();
274 UpdateSessionLengthLimit();
276 local_state_registrar_->Add(
277 prefs::kSessionStartTime,
278 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime,
279 base::Unretained(this)));
280 local_state_registrar_->Add(
281 prefs::kSessionLengthLimit,
282 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit,
283 base::Unretained(this)));
285 policy::BrowserPolicyConnectorChromeOS* policy_connector =
286 g_browser_process->platform_part()->browser_policy_connector_chromeos();
287 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
288 policy_connector->GetDeviceCloudPolicyManager();
289 if (policy_manager)
290 policy_manager->core()->store()->AddObserver(this);
291 UpdateEnterpriseDomain();
294 SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() {
295 // Unregister PrefChangeRegistrars.
296 local_state_registrar_.reset();
297 user_pref_registrar_.reset();
299 // Unregister content notifications before destroying any components.
300 registrar_.reset();
302 // Unregister a11y status subscription.
303 accessibility_subscription_.reset();
305 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
306 input_method::InputMethodManager::Get()->RemoveObserver(this);
307 ui::ime::InputMethodMenuManager::GetInstance()->RemoveObserver(this);
308 bluetooth_adapter_->RemoveObserver(this);
309 ash::Shell::GetInstance()
310 ->session_state_delegate()
311 ->RemoveSessionStateObserver(this);
312 LoginState::Get()->RemoveObserver(this);
314 if (CrasAudioHandler::IsInitialized())
315 CrasAudioHandler::Get()->RemoveAudioObserver(this);
317 BrowserList::RemoveObserver(this);
318 StopObservingAppWindowRegistry();
319 StopObservingCustodianInfoChanges();
321 policy::BrowserPolicyConnectorChromeOS* connector =
322 g_browser_process->platform_part()->browser_policy_connector_chromeos();
323 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
324 connector->GetDeviceCloudPolicyManager();
325 if (policy_manager)
326 policy_manager->core()->store()->RemoveObserver(this);
328 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
331 // Overridden from ash::SystemTrayDelegate:
332 bool SystemTrayDelegateChromeOS::GetTrayVisibilityOnStartup() {
333 // In case of OOBE / sign in screen tray will be shown later.
334 return LoginState::Get()->IsUserLoggedIn();
337 ash::user::LoginStatus SystemTrayDelegateChromeOS::GetUserLoginStatus() const {
338 // All non-logged in ChromeOS specific LOGGED_IN states map to the same
339 // Ash specific LOGGED_IN state.
340 if (!LoginState::Get()->IsUserLoggedIn())
341 return ash::user::LOGGED_IN_NONE;
343 if (screen_locked_)
344 return ash::user::LOGGED_IN_LOCKED;
346 LoginState::LoggedInUserType user_type =
347 LoginState::Get()->GetLoggedInUserType();
348 switch (user_type) {
349 case LoginState::LOGGED_IN_USER_NONE:
350 return ash::user::LOGGED_IN_NONE;
351 case LoginState::LOGGED_IN_USER_REGULAR:
352 return ash::user::LOGGED_IN_USER;
353 case LoginState::LOGGED_IN_USER_OWNER:
354 return ash::user::LOGGED_IN_OWNER;
355 case LoginState::LOGGED_IN_USER_GUEST:
356 return ash::user::LOGGED_IN_GUEST;
357 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
358 return ash::user::LOGGED_IN_PUBLIC;
359 case LoginState::LOGGED_IN_USER_SUPERVISED:
360 return ash::user::LOGGED_IN_SUPERVISED;
361 case LoginState::LOGGED_IN_USER_KIOSK_APP:
362 return ash::user::LOGGED_IN_KIOSK_APP;
364 NOTREACHED();
365 return ash::user::LOGGED_IN_NONE;
368 void SystemTrayDelegateChromeOS::ChangeProfilePicture() {
369 content::RecordAction(
370 base::UserMetricsAction("OpenChangeProfilePictureDialog"));
371 ShowSettingsSubPageForActiveUser(chrome::kChangeProfilePictureSubPage);
374 const std::string SystemTrayDelegateChromeOS::GetEnterpriseDomain() const {
375 return enterprise_domain_;
378 const base::string16 SystemTrayDelegateChromeOS::GetEnterpriseMessage() const {
379 if (GetEnterpriseDomain().empty())
380 return base::string16();
381 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE,
382 base::UTF8ToUTF16(GetEnterpriseDomain()));
385 const std::string SystemTrayDelegateChromeOS::GetSupervisedUserManager() const {
386 if (!IsUserSupervised())
387 return std::string();
388 return SupervisedUserServiceFactory::GetForProfile(user_profile_)->
389 GetCustodianEmailAddress();
392 const base::string16
393 SystemTrayDelegateChromeOS::GetSupervisedUserManagerName() const {
394 if (!IsUserSupervised())
395 return base::string16();
396 return base::UTF8ToUTF16(SupervisedUserServiceFactory::GetForProfile(
397 user_profile_)->GetCustodianName());
400 const base::string16 SystemTrayDelegateChromeOS::GetSupervisedUserMessage()
401 const {
402 if (!IsUserSupervised())
403 return base::string16();
404 if (IsUserChild())
405 return GetChildUserMessage();
406 return GetLegacySupervisedUserMessage();
409 bool SystemTrayDelegateChromeOS::IsUserSupervised() const {
410 user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser();
411 return user && user->IsSupervised();
414 bool SystemTrayDelegateChromeOS::IsUserChild() const {
415 return user_manager::UserManager::Get()->IsLoggedInAsChildUser();
418 void SystemTrayDelegateChromeOS::GetSystemUpdateInfo(
419 ash::UpdateInfo* info) const {
420 GetUpdateInfo(UpgradeDetector::GetInstance(), info);
423 base::HourClockType SystemTrayDelegateChromeOS::GetHourClockType() const {
424 return clock_type_;
427 void SystemTrayDelegateChromeOS::ShowSettings() {
428 ShowSettingsSubPageForActiveUser("");
431 bool SystemTrayDelegateChromeOS::ShouldShowSettings() {
432 return ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings() &&
433 !ash::Shell::GetInstance()
434 ->session_state_delegate()
435 ->IsInSecondaryLoginScreen();
438 void SystemTrayDelegateChromeOS::ShowDateSettings() {
439 content::RecordAction(base::UserMetricsAction("ShowDateOptions"));
440 std::string sub_page =
441 std::string(chrome::kSearchSubPage) + "#" +
442 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
443 // Everybody can change the time zone (even though it is a device setting).
444 ShowSettingsSubPageForActiveUser(sub_page);
447 void SystemTrayDelegateChromeOS::ShowSetTimeDialog() {
448 SetTimeDialog::ShowDialog(GetNativeWindow());
451 void SystemTrayDelegateChromeOS::ShowNetworkSettingsForGuid(
452 const std::string& guid) {
453 bool userAddingRunning = ash::Shell::GetInstance()
454 ->session_state_delegate()
455 ->IsInSecondaryLoginScreen();
457 if (!LoginState::Get()->IsUserLoggedIn() || userAddingRunning)
458 return;
459 std::string page = chrome::kInternetOptionsSubPage;
460 if (!guid.empty())
461 page += "?guid=" + net::EscapeUrlEncodedData(guid, true);
462 content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog"));
463 ShowSettingsSubPageForActiveUser(page);
466 void SystemTrayDelegateChromeOS::ShowBluetoothSettings() {
467 // TODO(sad): Make this work.
470 void SystemTrayDelegateChromeOS::ShowDisplaySettings() {
471 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions"));
472 ShowSettingsSubPageForActiveUser(kDisplaySettingsSubPageName);
475 void SystemTrayDelegateChromeOS::ShowChromeSlow() {
476 chrome::ScopedTabbedBrowserDisplayer displayer(
477 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
478 chrome::ShowSlow(displayer.browser());
481 bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() {
482 // Packaged app is not counted as 'last active', so if a browser opening the
483 // display settings is in background of a packaged app, it will return true.
484 // TODO(mukai): fix this.
485 Browser* active_browser =
486 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH);
487 if (!active_browser)
488 return true;
490 content::WebContents* active_contents =
491 active_browser->tab_strip_model()->GetActiveWebContents();
492 if (!active_contents)
493 return true;
495 GURL visible_url = active_contents->GetLastCommittedURL();
496 GURL display_settings_url =
497 chrome::GetSettingsUrl(kDisplaySettingsSubPageName);
498 GURL display_overscan_url =
499 chrome::GetSettingsUrl(kDisplayOverscanSettingsSubPageName);
500 return (visible_url != display_settings_url &&
501 visible_url != display_overscan_url);
504 void SystemTrayDelegateChromeOS::ShowIMESettings() {
505 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog"));
506 ShowSettingsSubPageForActiveUser(chrome::kLanguageOptionsSubPage);
509 void SystemTrayDelegateChromeOS::ShowHelp() {
510 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(),
511 chrome::HOST_DESKTOP_TYPE_ASH,
512 chrome::HELP_SOURCE_MENU);
515 void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() {
516 chrome::ScopedTabbedBrowserDisplayer displayer(
517 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
518 accessibility::ShowAccessibilityHelp(displayer.browser());
521 void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() {
522 content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings"));
523 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
524 l10n_util::GetStringUTF8(
525 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY);
526 ShowSettingsSubPageForActiveUser(sub_page);
529 void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() {
530 chrome::ScopedTabbedBrowserDisplayer displayer(
531 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
532 chrome::ShowPolicy(displayer.browser());
535 void SystemTrayDelegateChromeOS::ShowSupervisedUserInfo() {
536 // TODO(antrim): find out what should we show in this case.
537 // http://crbug.com/229762
540 void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() {
541 ash::user::LoginStatus status = GetUserLoginStatus();
542 bool userAddingRunning = ash::Shell::GetInstance()
543 ->session_state_delegate()
544 ->IsInSecondaryLoginScreen();
546 if (status == ash::user::LOGGED_IN_NONE ||
547 status == ash::user::LOGGED_IN_LOCKED || userAddingRunning) {
548 scoped_refptr<chromeos::HelpAppLauncher> help_app(
549 new chromeos::HelpAppLauncher(GetNativeWindow()));
550 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE);
551 } else {
552 chrome::ScopedTabbedBrowserDisplayer displayer(
553 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
554 chrome::ShowSingletonTab(displayer.browser(),
555 GURL(chrome::kLearnMoreEnterpriseURL));
559 void SystemTrayDelegateChromeOS::ShowUserLogin() {
560 ash::Shell* shell = ash::Shell::GetInstance();
561 if (!shell->delegate()->IsMultiProfilesEnabled())
562 return;
564 // Only regular non-supervised users could add other users to current session.
565 if (user_manager::UserManager::Get()->GetActiveUser()->GetType() !=
566 user_manager::USER_TYPE_REGULAR) {
567 return;
570 if (static_cast<int>(
571 user_manager::UserManager::Get()->GetLoggedInUsers().size()) >=
572 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers())
573 return;
575 // Launch sign in screen to add another user to current session.
576 if (user_manager::UserManager::Get()
577 ->GetUsersAllowedForMultiProfile()
578 .size()) {
579 // Don't show dialog if any logged in user in multi-profiles session
580 // dismissed it.
581 bool show_intro = true;
582 const user_manager::UserList logged_in_users =
583 user_manager::UserManager::Get()->GetLoggedInUsers();
584 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
585 it != logged_in_users.end();
586 ++it) {
587 show_intro &= !multi_user_util::GetProfileFromUserID(
588 multi_user_util::GetUserIDFromEmail((*it)->email()))
589 ->GetPrefs()
590 ->GetBoolean(prefs::kMultiProfileNeverShowIntro);
591 if (!show_intro)
592 break;
594 if (show_intro) {
595 base::Callback<void(bool)> on_accept =
596 base::Bind(&OnAcceptMultiprofilesIntro);
597 ShowMultiprofilesIntroDialog(on_accept);
598 } else {
599 UserAddingScreen::Get()->Start();
604 void SystemTrayDelegateChromeOS::SignOut() {
605 chrome::AttemptUserExit();
608 void SystemTrayDelegateChromeOS::RequestLockScreen() {
609 // TODO(antrim) : additional logging for crbug/173178
610 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate";
611 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
614 void SystemTrayDelegateChromeOS::RequestRestartForUpdate() {
615 // We expect that UpdateEngine is in "Reboot for update" state now.
616 chrome::NotifyAndTerminate(true /* fast path */);
619 void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices(
620 ash::BluetoothDeviceList* list) {
621 device::BluetoothAdapter::DeviceList devices =
622 bluetooth_adapter_->GetDevices();
623 for (size_t i = 0; i < devices.size(); ++i) {
624 device::BluetoothDevice* device = devices[i];
625 ash::BluetoothDeviceInfo info;
626 info.address = device->GetAddress();
627 info.display_name = device->GetName();
628 info.connected = device->IsConnected();
629 info.connecting = device->IsConnecting();
630 info.paired = device->IsPaired();
631 list->push_back(info);
635 void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() {
636 if (GetBluetoothDiscovering()) {
637 LOG(WARNING) << "Already have active Bluetooth device discovery session.";
638 return;
640 VLOG(1) << "Requesting new Bluetooth device discovery session.";
641 should_run_bluetooth_discovery_ = true;
642 bluetooth_adapter_->StartDiscoverySession(
643 base::Bind(&SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession,
644 weak_ptr_factory_.GetWeakPtr()),
645 base::Bind(&BluetoothSetDiscoveringError));
648 void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() {
649 should_run_bluetooth_discovery_ = false;
650 if (!GetBluetoothDiscovering()) {
651 LOG(WARNING) << "No active Bluetooth device discovery session.";
652 return;
654 VLOG(1) << "Stopping Bluetooth device discovery session.";
655 bluetooth_discovery_session_->Stop(
656 base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError));
659 void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice(
660 const std::string& address) {
661 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
662 if (!device || device->IsConnecting() ||
663 (device->IsConnected() && device->IsPaired())) {
664 return;
666 if (device->IsPaired() && !device->IsConnectable())
667 return;
668 if (device->IsPaired() || !device->IsPairable()) {
669 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
670 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE);
671 device->Connect(NULL,
672 base::Bind(&base::DoNothing),
673 base::Bind(&BluetoothDeviceConnectError));
674 } else { // Show paring dialog for the unpaired device.
675 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
676 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE);
677 BluetoothPairingDialog* dialog =
678 new BluetoothPairingDialog(GetNativeWindow(), device);
679 // The dialog deletes itself on close.
680 dialog->Show();
684 bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() {
685 return bluetooth_adapter_->IsDiscovering();
688 void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) {
689 input_method::InputMethodManager* manager =
690 input_method::InputMethodManager::Get();
691 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
692 input_method::InputMethodDescriptor ime =
693 manager->GetActiveIMEState()->GetCurrentInputMethod();
694 ExtractIMEInfo(ime, *util, info);
695 info->selected = true;
698 void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) {
699 input_method::InputMethodManager* manager =
700 input_method::InputMethodManager::Get();
701 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
702 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors(
703 manager->GetActiveIMEState()->GetActiveInputMethods());
704 std::string current =
705 manager->GetActiveIMEState()->GetCurrentInputMethod().id();
706 for (size_t i = 0; i < ime_descriptors->size(); i++) {
707 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i);
708 ash::IMEInfo info;
709 ExtractIMEInfo(ime, *util, &info);
710 info.selected = ime.id() == current;
711 list->push_back(info);
715 void SystemTrayDelegateChromeOS::GetCurrentIMEProperties(
716 ash::IMEPropertyInfoList* list) {
717 ui::ime::InputMethodMenuItemList menu_list =
718 ui::ime::InputMethodMenuManager::GetInstance()->
719 GetCurrentInputMethodMenuItemList();
720 for (size_t i = 0; i < menu_list.size(); ++i) {
721 ash::IMEPropertyInfo property;
722 property.key = menu_list[i].key;
723 property.name = base::UTF8ToUTF16(menu_list[i].label);
724 property.selected = menu_list[i].is_selection_item_checked;
725 list->push_back(property);
729 void SystemTrayDelegateChromeOS::SwitchIME(const std::string& ime_id) {
730 input_method::InputMethodManager::Get()
731 ->GetActiveIMEState()
732 ->ChangeInputMethod(ime_id, false /* show_message */);
733 input_method::InputMethodSwitchRecorder::Get()->RecordSwitch(
734 true /* by_tray_menu */);
737 void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string& key) {
738 input_method::InputMethodManager::Get()->ActivateInputMethodMenuItem(key);
741 void SystemTrayDelegateChromeOS::ManageBluetoothDevices() {
742 content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage"));
743 std::string sub_page =
744 std::string(chrome::kSearchSubPage) + "#" +
745 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH);
746 ShowSettingsSubPageForActiveUser(sub_page);
749 void SystemTrayDelegateChromeOS::ToggleBluetooth() {
750 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(),
751 base::Bind(&base::DoNothing),
752 base::Bind(&BluetoothPowerFailure));
755 void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog(
756 const std::string& type) {
757 if (type == shill::kTypeCellular) {
758 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
759 return;
761 NetworkConfigView::ShowForType(type, GetNativeWindow());
764 bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() {
765 return bluetooth_adapter_->IsPresent();
768 bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() {
769 return bluetooth_adapter_->IsPowered();
772 bool SystemTrayDelegateChromeOS::GetBluetoothDiscovering() {
773 return (bluetooth_discovery_session_.get() &&
774 bluetooth_discovery_session_->IsActive());
777 void SystemTrayDelegateChromeOS::ChangeProxySettings() {
778 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE);
779 LoginDisplayHostImpl::default_host()->OpenProxySettings();
782 ash::NetworkingConfigDelegate*
783 SystemTrayDelegateChromeOS::GetNetworkingConfigDelegate() const {
784 return networking_config_delegate_.get();
787 ash::VolumeControlDelegate*
788 SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const {
789 return volume_control_delegate_.get();
792 void SystemTrayDelegateChromeOS::SetVolumeControlDelegate(
793 scoped_ptr<ash::VolumeControlDelegate> delegate) {
794 volume_control_delegate_.swap(delegate);
797 bool SystemTrayDelegateChromeOS::GetSessionStartTime(
798 base::TimeTicks* session_start_time) {
799 *session_start_time = session_start_time_;
800 return have_session_start_time_;
803 bool SystemTrayDelegateChromeOS::GetSessionLengthLimit(
804 base::TimeDelta* session_length_limit) {
805 *session_length_limit = session_length_limit_;
806 return have_session_length_limit_;
809 int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() {
810 return l10n_util::GetLocalizedContentsWidthInPixels(
811 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS);
814 void SystemTrayDelegateChromeOS::ActiveUserWasChanged() {
815 SetProfile(ProfileManager::GetActiveUserProfile());
816 GetSystemTrayNotifier()->NotifyUserUpdate();
819 bool SystemTrayDelegateChromeOS::IsSearchKeyMappedToCapsLock() {
820 return search_key_mapped_to_ == input_method::kCapsLockKey;
823 ash::tray::UserAccountsDelegate*
824 SystemTrayDelegateChromeOS::GetUserAccountsDelegate(
825 const std::string& user_id) {
826 if (!accounts_delegates_.contains(user_id)) {
827 const user_manager::User* user =
828 user_manager::UserManager::Get()->FindUser(user_id);
829 Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
830 CHECK(user_profile);
831 accounts_delegates_.set(
832 user_id,
833 scoped_ptr<ash::tray::UserAccountsDelegate>(
834 new UserAccountsDelegateChromeOS(user_profile)));
836 return accounts_delegates_.get(user_id);
839 void SystemTrayDelegateChromeOS::AddCustodianInfoTrayObserver(
840 ash::CustodianInfoTrayObserver* observer) {
841 custodian_info_changed_observers_.AddObserver(observer);
844 void SystemTrayDelegateChromeOS::RemoveCustodianInfoTrayObserver(
845 ash::CustodianInfoTrayObserver* observer) {
846 custodian_info_changed_observers_.RemoveObserver(observer);
849 void SystemTrayDelegateChromeOS::AddShutdownPolicyObserver(
850 ash::ShutdownPolicyObserver* observer) {
851 shutdown_policy_observers_.AddObserver(observer);
854 void SystemTrayDelegateChromeOS::RemoveShutdownPolicyObserver(
855 ash::ShutdownPolicyObserver* observer) {
856 shutdown_policy_observers_.RemoveObserver(observer);
859 void SystemTrayDelegateChromeOS::ShouldRebootOnShutdown(
860 const ash::RebootOnShutdownCallback& callback) {
861 shutdown_policy_handler_->CheckIfRebootOnShutdown(callback);
864 ash::VPNDelegate* SystemTrayDelegateChromeOS::GetVPNDelegate() const {
865 return vpn_delegate_.get();
868 void SystemTrayDelegateChromeOS::UserAddedToSession(
869 const user_manager::User* active_user) {
872 void SystemTrayDelegateChromeOS::ActiveUserChanged(
873 const user_manager::User* /* active_user */) {
876 void SystemTrayDelegateChromeOS::UserChangedChildStatus(
877 user_manager::User* user) {
878 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(user);
880 // Returned user_profile might be NULL on restoring Users on browser start.
881 // At some point profile is not yet fully initiated.
882 if (session_started_ &&
883 user_profile != NULL &&
884 user_profile_ == user_profile) {
885 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
886 GetUserLoginStatus());
890 ash::SystemTray* SystemTrayDelegateChromeOS::GetPrimarySystemTray() {
891 return ash::Shell::GetInstance()->GetPrimarySystemTray();
894 ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() {
895 return ash::Shell::GetInstance()->system_tray_notifier();
898 void SystemTrayDelegateChromeOS::SetProfile(Profile* profile) {
899 // Stop observing the AppWindowRegistry of the current |user_profile_|.
900 StopObservingAppWindowRegistry();
902 // Stop observing custodian info changes of the current |user_profile_|.
903 StopObservingCustodianInfoChanges();
905 user_profile_ = profile;
907 // Start observing the AppWindowRegistry of the newly set |user_profile_|.
908 extensions::AppWindowRegistry::Get(user_profile_)->AddObserver(this);
910 // Start observing custodian info changes of the newly set |user_profile_|.
911 SupervisedUserServiceFactory::GetForProfile(profile)->AddObserver(this);
913 PrefService* prefs = profile->GetPrefs();
914 user_pref_registrar_.reset(new PrefChangeRegistrar);
915 user_pref_registrar_->Init(prefs);
916 user_pref_registrar_->Add(
917 prefs::kUse24HourClock,
918 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
919 base::Unretained(this)));
920 user_pref_registrar_->Add(
921 prefs::kLanguageRemapSearchKeyTo,
922 base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged,
923 base::Unretained(this)));
924 user_pref_registrar_->Add(
925 prefs::kShowLogoutButtonInTray,
926 base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray,
927 base::Unretained(this)));
928 user_pref_registrar_->Add(
929 prefs::kLogoutDialogDurationMs,
930 base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration,
931 base::Unretained(this)));
932 user_pref_registrar_->Add(
933 prefs::kAccessibilityLargeCursorEnabled,
934 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
935 base::Unretained(this),
936 ui::A11Y_NOTIFICATION_NONE));
937 user_pref_registrar_->Add(
938 prefs::kAccessibilityAutoclickEnabled,
939 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
940 base::Unretained(this),
941 ui::A11Y_NOTIFICATION_NONE));
942 user_pref_registrar_->Add(
943 prefs::kShouldAlwaysShowAccessibilityMenu,
944 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
945 base::Unretained(this),
946 ui::A11Y_NOTIFICATION_NONE));
947 user_pref_registrar_->Add(
948 prefs::kPerformanceTracingEnabled,
949 base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing,
950 base::Unretained(this)));
952 UpdateShowLogoutButtonInTray();
953 UpdateLogoutDialogDuration();
954 UpdatePerformanceTracing();
955 OnCustodianInfoChanged();
956 search_key_mapped_to_ =
957 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo);
960 bool SystemTrayDelegateChromeOS::UnsetProfile(Profile* profile) {
961 if (profile != user_profile_)
962 return false;
963 user_pref_registrar_.reset();
964 user_profile_ = NULL;
965 return true;
968 bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const {
969 return ShouldUse24HourClock();
972 bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const {
973 // On login screen and in guest mode owner default is used for
974 // kUse24HourClock preference.
975 const ash::user::LoginStatus status = GetUserLoginStatus();
976 const CrosSettings* const cros_settings = CrosSettings::Get();
977 bool system_use_24_hour_clock = true;
978 const bool system_value_found = cros_settings->GetBoolean(
979 kSystemUse24HourClock, &system_use_24_hour_clock);
981 if ((status == ash::user::LOGGED_IN_NONE) || !user_pref_registrar_)
982 return (system_value_found
983 ? system_use_24_hour_clock
984 : (base::GetHourClockType() == base::k24HourClock));
986 const PrefService::Preference* user_pref =
987 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock);
988 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue())
989 return (system_value_found
990 ? system_use_24_hour_clock
991 : (base::GetHourClockType() == base::k24HourClock));
993 user_manager::User* active_user =
994 user_manager::UserManager::Get()->GetActiveUser();
995 if (active_user) {
996 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(active_user);
997 if (user_profile) {
998 user_pref =
999 user_profile->GetPrefs()->FindPreference(prefs::kUse24HourClock);
1003 bool use_24_hour_clock = true;
1004 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock);
1005 return use_24_hour_clock;
1008 void SystemTrayDelegateChromeOS::UpdateClockType() {
1009 const bool use_24_hour_clock = ShouldUse24HourClock();
1010 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock;
1011 GetSystemTrayNotifier()->NotifyDateFormatChanged();
1012 // This also works for enterprise-managed devices because they never have
1013 // local owner.
1014 if (user_manager::UserManager::Get()->IsCurrentUserOwner())
1015 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
1018 void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() {
1019 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
1020 user_pref_registrar_->prefs()->GetBoolean(
1021 prefs::kShowLogoutButtonInTray));
1024 void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() {
1025 const int duration_ms =
1026 user_pref_registrar_->prefs()->GetInteger(prefs::kLogoutDialogDurationMs);
1027 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged(
1028 base::TimeDelta::FromMilliseconds(duration_ms));
1031 void SystemTrayDelegateChromeOS::UpdateSessionStartTime() {
1032 const PrefService* local_state = local_state_registrar_->prefs();
1033 if (local_state->HasPrefPath(prefs::kSessionStartTime)) {
1034 have_session_start_time_ = true;
1035 session_start_time_ = base::TimeTicks::FromInternalValue(
1036 local_state->GetInt64(prefs::kSessionStartTime));
1037 } else {
1038 have_session_start_time_ = false;
1039 session_start_time_ = base::TimeTicks();
1041 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
1044 void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() {
1045 const PrefService* local_state = local_state_registrar_->prefs();
1046 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) {
1047 have_session_length_limit_ = true;
1048 session_length_limit_ = base::TimeDelta::FromMilliseconds(
1049 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit),
1050 kSessionLengthLimitMinMs),
1051 kSessionLengthLimitMaxMs));
1052 } else {
1053 have_session_length_limit_ = false;
1054 session_length_limit_ = base::TimeDelta();
1056 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
1059 void SystemTrayDelegateChromeOS::StopObservingAppWindowRegistry() {
1060 if (!user_profile_)
1061 return;
1063 extensions::AppWindowRegistry* registry =
1064 extensions::AppWindowRegistry::Factory::GetForBrowserContext(
1065 user_profile_, false);
1066 if (registry)
1067 registry->RemoveObserver(this);
1070 void SystemTrayDelegateChromeOS::StopObservingCustodianInfoChanges() {
1071 if (!user_profile_)
1072 return;
1074 SupervisedUserService* service = SupervisedUserServiceFactory::GetForProfile(
1075 user_profile_);
1076 if (service)
1077 service->RemoveObserver(this);
1080 void SystemTrayDelegateChromeOS::NotifyIfLastWindowClosed() {
1081 if (!user_profile_)
1082 return;
1084 BrowserList* browser_list =
1085 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
1086 for (BrowserList::const_iterator it = browser_list->begin();
1087 it != browser_list->end();
1088 ++it) {
1089 if ((*it)->profile()->IsSameProfile(user_profile_)) {
1090 // The current user has at least one open browser window.
1091 return;
1095 if (!extensions::AppWindowRegistry::Get(
1096 user_profile_)->app_windows().empty()) {
1097 // The current user has at least one open app window.
1098 return;
1101 GetSystemTrayNotifier()->NotifyLastWindowClosed();
1104 // LoginState::Observer overrides.
1105 void SystemTrayDelegateChromeOS::LoggedInStateChanged() {
1106 // It apparently sometimes takes a while after login before the current user
1107 // is recognized as the owner. Make sure that the system-wide clock setting
1108 // is updated when the recognition eventually happens
1109 // (http://crbug.com/278601).
1111 // Note that it isn't safe to blindly call UpdateClockType() from this
1112 // method, as LoggedInStateChanged() is also called before the logged-in
1113 // user's profile has actually been loaded (http://crbug.com/317745). The
1114 // system tray's time format is updated at login via SetProfile().
1115 if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
1116 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock,
1117 ShouldUse24HourClock());
1121 // Overridden from SessionManagerClient::Observer.
1122 void SystemTrayDelegateChromeOS::ScreenIsLocked() {
1123 screen_locked_ = true;
1124 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1127 void SystemTrayDelegateChromeOS::ScreenIsUnlocked() {
1128 screen_locked_ = false;
1129 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1132 gfx::NativeWindow SystemTrayDelegateChromeOS::GetNativeWindow() const {
1133 bool session_started = ash::Shell::GetInstance()
1134 ->session_state_delegate()
1135 ->IsActiveUserSessionStarted();
1136 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started);
1139 // content::NotificationObserver implementation.
1140 void SystemTrayDelegateChromeOS::Observe(
1141 int type,
1142 const content::NotificationSource& source,
1143 const content::NotificationDetails& details) {
1144 switch (type) {
1145 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
1146 UpdateClockType();
1147 break;
1149 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
1150 ash::UpdateInfo info;
1151 GetUpdateInfo(content::Source<UpgradeDetector>(source).ptr(), &info);
1152 GetSystemTrayNotifier()->NotifyUpdateRecommended(info);
1153 break;
1155 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
1156 // This notification is also sent on login screen when user avatar
1157 // is loaded from file.
1158 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) {
1159 GetSystemTrayNotifier()->NotifyUserUpdate();
1161 break;
1163 case chrome::NOTIFICATION_PROFILE_CREATED: {
1164 SetProfile(content::Source<Profile>(source).ptr());
1165 registrar_->Remove(this,
1166 chrome::NOTIFICATION_PROFILE_CREATED,
1167 content::NotificationService::AllSources());
1168 break;
1170 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1171 if (UnsetProfile(content::Source<Profile>(source).ptr())) {
1172 registrar_->Remove(this,
1173 chrome::NOTIFICATION_PROFILE_DESTROYED,
1174 content::NotificationService::AllSources());
1176 break;
1178 case chrome::NOTIFICATION_SESSION_STARTED: {
1179 session_started_ = true;
1180 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1181 GetUserLoginStatus());
1182 SetProfile(ProfileManager::GetActiveUserProfile());
1183 break;
1185 default:
1186 NOTREACHED();
1190 void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() {
1191 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger(
1192 prefs::kLanguageRemapSearchKeyTo);
1195 void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged(
1196 ui::AccessibilityNotificationVisibility notify) {
1197 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify);
1200 void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() {
1201 if (!user_pref_registrar_)
1202 return;
1203 bool value = user_pref_registrar_->prefs()->GetBoolean(
1204 prefs::kPerformanceTracingEnabled);
1205 GetSystemTrayNotifier()->NotifyTracingModeChanged(value);
1208 // Overridden from InputMethodManager::Observer.
1209 void SystemTrayDelegateChromeOS::InputMethodChanged(
1210 input_method::InputMethodManager* manager,
1211 bool show_message) {
1212 GetSystemTrayNotifier()->NotifyRefreshIME();
1215 // Overridden from InputMethodMenuManager::Observer.
1216 void SystemTrayDelegateChromeOS::InputMethodMenuItemChanged(
1217 ui::ime::InputMethodMenuManager* manager) {
1218 GetSystemTrayNotifier()->NotifyRefreshIME();
1221 // Overridden from CrasAudioHandler::AudioObserver.
1222 void SystemTrayDelegateChromeOS::OnOutputNodeVolumeChanged(uint64_t node_id,
1223 int volume) {
1224 GetSystemTrayNotifier()->NotifyAudioOutputVolumeChanged(node_id, volume);
1227 void SystemTrayDelegateChromeOS::OnOutputMuteChanged(bool mute_on) {
1228 GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged(mute_on);
1231 void SystemTrayDelegateChromeOS::OnInputNodeGainChanged(uint64_t /* node_id */,
1232 int /* gain */) {
1235 void SystemTrayDelegateChromeOS::OnInputMuteChanged(bool /* mute_on */) {
1238 void SystemTrayDelegateChromeOS::OnAudioNodesChanged() {
1239 GetSystemTrayNotifier()->NotifyAudioNodesChanged();
1242 void SystemTrayDelegateChromeOS::OnActiveOutputNodeChanged() {
1243 GetSystemTrayNotifier()->NotifyAudioActiveOutputNodeChanged();
1246 void SystemTrayDelegateChromeOS::OnActiveInputNodeChanged() {
1247 GetSystemTrayNotifier()->NotifyAudioActiveInputNodeChanged();
1250 // Overridden from BluetoothAdapter::Observer.
1251 void SystemTrayDelegateChromeOS::AdapterPresentChanged(
1252 device::BluetoothAdapter* adapter,
1253 bool present) {
1254 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1257 void SystemTrayDelegateChromeOS::AdapterPoweredChanged(
1258 device::BluetoothAdapter* adapter,
1259 bool powered) {
1260 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1263 void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged(
1264 device::BluetoothAdapter* adapter,
1265 bool discovering) {
1266 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1269 void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter* adapter,
1270 device::BluetoothDevice* device) {
1271 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1274 void SystemTrayDelegateChromeOS::DeviceChanged(
1275 device::BluetoothAdapter* adapter,
1276 device::BluetoothDevice* device) {
1277 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1280 void SystemTrayDelegateChromeOS::DeviceRemoved(
1281 device::BluetoothAdapter* adapter,
1282 device::BluetoothDevice* device) {
1283 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1286 void SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession(
1287 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
1288 // If the discovery session was returned after a request to stop discovery
1289 // (e.g. the user dismissed the Bluetooth detailed view before the call
1290 // returned), don't claim the discovery session and let it clean up.
1291 if (!should_run_bluetooth_discovery_)
1292 return;
1293 VLOG(1) << "Claiming new Bluetooth device discovery session.";
1294 bluetooth_discovery_session_ = discovery_session.Pass();
1295 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1298 void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() {
1299 policy::BrowserPolicyConnectorChromeOS* connector =
1300 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1301 std::string enterprise_domain = connector->GetEnterpriseDomain();
1302 if (enterprise_domain_ != enterprise_domain) {
1303 enterprise_domain_ = enterprise_domain;
1304 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1308 // Overridden from CloudPolicyStore::Observer
1309 void SystemTrayDelegateChromeOS::OnStoreLoaded(
1310 policy::CloudPolicyStore* store) {
1311 UpdateEnterpriseDomain();
1314 void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore* store) {
1315 UpdateEnterpriseDomain();
1318 // Overridden from ash::SessionStateObserver
1319 void SystemTrayDelegateChromeOS::UserAddedToSession(
1320 const std::string& user_id) {
1321 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1324 void SystemTrayDelegateChromeOS::ActiveUserChanged(
1325 const std::string& /* user_id */) {
1326 UpdateClockType();
1329 // Overridden from chrome::BrowserListObserver.
1330 void SystemTrayDelegateChromeOS::OnBrowserRemoved(Browser* browser) {
1331 NotifyIfLastWindowClosed();
1334 // Overridden from extensions::AppWindowRegistry::Observer.
1335 void SystemTrayDelegateChromeOS::OnAppWindowRemoved(
1336 extensions::AppWindow* app_window) {
1337 NotifyIfLastWindowClosed();
1340 // Overridden from SupervisedUserServiceObserver.
1341 void SystemTrayDelegateChromeOS::OnCustodianInfoChanged() {
1342 FOR_EACH_OBSERVER(
1343 ash::CustodianInfoTrayObserver, custodian_info_changed_observers_,
1344 OnCustodianInfoChanged());
1347 void SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged(
1348 const AccessibilityStatusEventDetails& details) {
1349 if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN)
1350 accessibility_subscription_.reset();
1351 else
1352 OnAccessibilityModeChanged(details.notify);
1355 void SystemTrayDelegateChromeOS::OnShutdownPolicyChanged(
1356 bool reboot_on_shutdown) {
1357 // Notify all observers.
1358 FOR_EACH_OBSERVER(ash::ShutdownPolicyObserver, shutdown_policy_observers_,
1359 OnShutdownPolicyChanged(reboot_on_shutdown));
1362 const base::string16
1363 SystemTrayDelegateChromeOS::GetLegacySupervisedUserMessage() const {
1364 std::string user_manager_name = GetSupervisedUserManager();
1365 return l10n_util::GetStringFUTF16(
1366 IDS_USER_IS_SUPERVISED_BY_NOTICE,
1367 base::UTF8ToUTF16(user_manager_name));
1370 const base::string16
1371 SystemTrayDelegateChromeOS::GetChildUserMessage() const {
1372 #if defined(ENABLE_SUPERVISED_USERS)
1373 SupervisedUserService* service =
1374 SupervisedUserServiceFactory::GetForProfile(user_profile_);
1375 base::string16 first_custodian =
1376 base::UTF8ToUTF16(service->GetCustodianEmailAddress());
1377 base::string16 second_custodian =
1378 base::UTF8ToUTF16(service->GetSecondCustodianEmailAddress());
1379 LOG_IF(WARNING, first_custodian.empty()) <<
1380 "Returning incomplete child user message as manager not known yet.";
1381 if (second_custodian.empty()) {
1382 return l10n_util::GetStringFUTF16(
1383 IDS_CHILD_USER_IS_MANAGED_BY_ONE_PARENT_NOTICE, first_custodian);
1384 } else {
1385 return l10n_util::GetStringFUTF16(
1386 IDS_CHILD_USER_IS_MANAGED_BY_TWO_PARENTS_NOTICE,
1387 first_custodian,
1388 second_custodian);
1390 #endif
1392 LOG(WARNING) << "SystemTrayDelegateChromeOS::GetChildUserMessage call while "
1393 << "ENABLE_SUPERVISED_USERS undefined.";
1394 return base::string16();
1397 ash::SystemTrayDelegate* CreateSystemTrayDelegate() {
1398 return new SystemTrayDelegateChromeOS();
1401 } // namespace chromeos