Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / ash / system_tray_delegate_chromeos.cc
blobf4e1284145daa29df6ec5f3f7aee0a4f253b6661
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/display/display_manager.h"
15 #include "ash/metrics/user_metrics_recorder.h"
16 #include "ash/session/session_state_delegate.h"
17 #include "ash/session/session_state_observer.h"
18 #include "ash/shell.h"
19 #include "ash/shell_delegate.h"
20 #include "ash/shell_window_ids.h"
21 #include "ash/system/bluetooth/bluetooth_observer.h"
22 #include "ash/system/chromeos/session/logout_button_observer.h"
23 #include "ash/system/chromeos/shutdown_policy_observer.h"
24 #include "ash/system/date/clock_observer.h"
25 #include "ash/system/ime/ime_observer.h"
26 #include "ash/system/tray/system_tray.h"
27 #include "ash/system/tray/system_tray_delegate.h"
28 #include "ash/system/tray/system_tray_notifier.h"
29 #include "ash/system/tray_accessibility.h"
30 #include "ash/system/user/login_status.h"
31 #include "ash/system/user/update_observer.h"
32 #include "ash/system/user/user_observer.h"
33 #include "ash/volume_control_delegate.h"
34 #include "ash/wm/lock_state_controller.h"
35 #include "base/bind_helpers.h"
36 #include "base/callback.h"
37 #include "base/logging.h"
38 #include "base/memory/weak_ptr.h"
39 #include "base/prefs/pref_service.h"
40 #include "base/strings/stringprintf.h"
41 #include "base/strings/utf_string_conversions.h"
42 #include "base/sys_info.h"
43 #include "base/time/time.h"
44 #include "chrome/browser/browser_process.h"
45 #include "chrome/browser/chrome_notification_types.h"
46 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
47 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
48 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h"
49 #include "chrome/browser/chromeos/events/system_key_event_listener.h"
50 #include "chrome/browser/chromeos/input_method/input_method_switch_recorder.h"
51 #include "chrome/browser/chromeos/input_method/input_method_util.h"
52 #include "chrome/browser/chromeos/login/help_app_launcher.h"
53 #include "chrome/browser/chromeos/login/login_wizard.h"
54 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
55 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
56 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
57 #include "chrome/browser/chromeos/login/user_flow.h"
58 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
59 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
60 #include "chrome/browser/chromeos/options/network_config_view.h"
61 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
62 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
63 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
64 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
65 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
66 #include "chrome/browser/chromeos/profiles/profile_helper.h"
67 #include "chrome/browser/chromeos/set_time_dialog.h"
68 #include "chrome/browser/chromeos/settings/cros_settings.h"
69 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
70 #include "chrome/browser/lifetime/application_lifetime.h"
71 #include "chrome/browser/profiles/profile_manager.h"
72 #include "chrome/browser/supervised_user/supervised_user_service.h"
73 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
74 #include "chrome/browser/ui/ash/cast_config_delegate_chromeos.h"
75 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
76 #include "chrome/browser/ui/ash/networking_config_delegate_chromeos.h"
77 #include "chrome/browser/ui/ash/system_tray_delegate_utils.h"
78 #include "chrome/browser/ui/ash/user_accounts_delegate_chromeos.h"
79 #include "chrome/browser/ui/ash/volume_controller_chromeos.h"
80 #include "chrome/browser/ui/ash/vpn_delegate_chromeos.h"
81 #include "chrome/browser/ui/browser.h"
82 #include "chrome/browser/ui/browser_finder.h"
83 #include "chrome/browser/ui/browser_list.h"
84 #include "chrome/browser/ui/chrome_pages.h"
85 #include "chrome/browser/ui/host_desktop.h"
86 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
87 #include "chrome/browser/ui/singleton_tabs.h"
88 #include "chrome/browser/ui/tabs/tab_strip_model.h"
89 #include "chrome/browser/upgrade_detector.h"
90 #include "chrome/common/chrome_switches.h"
91 #include "chrome/common/pref_names.h"
92 #include "chrome/common/url_constants.h"
93 #include "chrome/grit/generated_resources.h"
94 #include "chrome/grit/locale_settings.h"
95 #include "chromeos/dbus/dbus_thread_manager.h"
96 #include "chromeos/dbus/session_manager_client.h"
97 #include "chromeos/login/login_state.h"
98 #include "chromeos/network/portal_detector/network_portal_detector.h"
99 #include "components/google/core/browser/google_util.h"
100 #include "components/policy/core/common/cloud/cloud_policy_store.h"
101 #include "components/user_manager/user.h"
102 #include "components/user_manager/user_manager.h"
103 #include "components/user_manager/user_type.h"
104 #include "content/public/browser/notification_observer.h"
105 #include "content/public/browser/notification_service.h"
106 #include "content/public/browser/user_metrics.h"
107 #include "content/public/browser/web_contents.h"
108 #include "device/bluetooth/bluetooth_adapter.h"
109 #include "device/bluetooth/bluetooth_adapter_factory.h"
110 #include "device/bluetooth/bluetooth_device.h"
111 #include "net/base/escape.h"
112 #include "third_party/cros_system_api/dbus/service_constants.h"
113 #include "ui/base/ime/chromeos/extension_ime_util.h"
114 #include "ui/base/ime/chromeos/ime_keyboard.h"
115 #include "ui/base/ime/chromeos/input_method_manager.h"
116 #include "ui/base/l10n/l10n_util.h"
117 #include "ui/base/l10n/time_format.h"
118 #include "ui/chromeos/ime/input_method_menu_item.h"
119 #include "ui/chromeos/ime/input_method_menu_manager.h"
121 #if defined(ENABLE_SUPERVISED_USERS)
122 #include "chrome/browser/supervised_user/supervised_user_service.h"
123 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
124 #endif
126 namespace chromeos {
128 namespace {
130 // The minimum session length limit that can be set.
131 const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
133 // The maximum session length limit that can be set.
134 const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
136 const char kDisplaySettingsSubPageName[] = "display";
137 const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan";
139 void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
140 const input_method::InputMethodUtil& util,
141 ash::IMEInfo* info) {
142 info->id = ime.id();
143 info->name = util.GetInputMethodLongName(ime);
144 info->medium_name = util.GetInputMethodMediumName(ime);
145 info->short_name = util.GetInputMethodShortName(ime);
146 info->third_party = extension_ime_util::IsExtensionIME(ime.id());
149 gfx::NativeWindow GetNativeWindowByStatus(ash::user::LoginStatus login_status,
150 bool session_started) {
151 bool isUserAddingRunning = ash::Shell::GetInstance()
152 ->session_state_delegate()
153 ->IsInSecondaryLoginScreen();
155 int container_id =
156 (!session_started || login_status == ash::user::LOGGED_IN_NONE ||
157 login_status == ash::user::LOGGED_IN_LOCKED || isUserAddingRunning)
158 ? ash::kShellWindowId_LockSystemModalContainer
159 : ash::kShellWindowId_SystemModalContainer;
160 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
161 container_id);
164 void BluetoothPowerFailure() {
165 // TODO(sad): Show an error bubble?
168 void BluetoothSetDiscoveringError() {
169 LOG(ERROR) << "BluetoothSetDiscovering failed.";
172 void BluetoothDeviceConnectError(
173 device::BluetoothDevice::ConnectErrorCode error_code) {
174 // TODO(sad): Do something?
177 void ShowSettingsSubPageForActiveUser(const std::string& sub_page) {
178 chrome::ShowSettingsSubPageForProfile(
179 ProfileManager::GetActiveUserProfile(), sub_page);
182 void OnAcceptMultiprofilesIntro(bool no_show_again) {
183 PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
184 prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again);
185 UserAddingScreen::Get()->Start();
188 } // namespace
190 SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
191 : user_profile_(NULL),
192 clock_type_(base::GetHourClockType()),
193 search_key_mapped_to_(input_method::kSearchKey),
194 screen_locked_(false),
195 have_session_start_time_(false),
196 have_session_length_limit_(false),
197 should_run_bluetooth_discovery_(false),
198 session_started_(false),
199 cast_config_delegate_(new CastConfigDelegateChromeos()),
200 networking_config_delegate_(new NetworkingConfigDelegateChromeos()),
201 volume_control_delegate_(new VolumeController()),
202 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
203 kSystemUse24HourClock,
204 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
205 base::Unretained(this)))),
206 vpn_delegate_(new VPNDelegateChromeOS),
207 weak_ptr_factory_(this) {
208 // Register notifications on construction so that events such as
209 // PROFILE_CREATED do not get missed if they happen before Initialize().
210 registrar_.reset(new content::NotificationRegistrar);
211 registrar_->Add(this,
212 chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
213 content::NotificationService::AllSources());
214 registrar_->Add(this,
215 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
216 content::NotificationService::AllSources());
217 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) {
218 registrar_->Add(this,
219 chrome::NOTIFICATION_SESSION_STARTED,
220 content::NotificationService::AllSources());
222 registrar_->Add(this,
223 chrome::NOTIFICATION_PROFILE_CREATED,
224 content::NotificationService::AllSources());
225 registrar_->Add(this,
226 chrome::NOTIFICATION_PROFILE_DESTROYED,
227 content::NotificationService::AllSources());
228 registrar_->Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
229 content::NotificationService::AllSources());
231 AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
232 CHECK(accessibility_manager);
233 accessibility_subscription_ = accessibility_manager->RegisterCallback(
234 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged,
235 base::Unretained(this)));
237 user_manager::UserManager::Get()->AddSessionStateObserver(this);
238 shutdown_policy_handler_.reset(
239 new ShutdownPolicyHandler(CrosSettings::Get(), this));
242 void SystemTrayDelegateChromeOS::Initialize() {
243 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
245 input_method::InputMethodManager::Get()->AddObserver(this);
246 ui::ime::InputMethodMenuManager::GetInstance()->AddObserver(this);
247 UpdateClockType();
249 device::BluetoothAdapterFactory::GetAdapter(
250 base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady,
251 weak_ptr_factory_.GetWeakPtr()));
253 ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(
254 this);
256 if (LoginState::IsInitialized())
257 LoginState::Get()->AddObserver(this);
259 if (CrasAudioHandler::IsInitialized())
260 CrasAudioHandler::Get()->AddAudioObserver(this);
262 BrowserList::AddObserver(this);
265 void SystemTrayDelegateChromeOS::Shutdown() {
266 device_settings_observer_.reset();
269 void SystemTrayDelegateChromeOS::InitializeOnAdapterReady(
270 scoped_refptr<device::BluetoothAdapter> adapter) {
271 bluetooth_adapter_ = adapter;
272 CHECK(bluetooth_adapter_.get());
273 bluetooth_adapter_->AddObserver(this);
275 local_state_registrar_.reset(new PrefChangeRegistrar);
276 local_state_registrar_->Init(g_browser_process->local_state());
278 UpdateSessionStartTime();
279 UpdateSessionLengthLimit();
281 local_state_registrar_->Add(
282 prefs::kSessionStartTime,
283 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime,
284 base::Unretained(this)));
285 local_state_registrar_->Add(
286 prefs::kSessionLengthLimit,
287 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit,
288 base::Unretained(this)));
290 policy::BrowserPolicyConnectorChromeOS* policy_connector =
291 g_browser_process->platform_part()->browser_policy_connector_chromeos();
292 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
293 policy_connector->GetDeviceCloudPolicyManager();
294 if (policy_manager)
295 policy_manager->core()->store()->AddObserver(this);
296 UpdateEnterpriseDomain();
299 SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() {
300 // Unregister PrefChangeRegistrars.
301 local_state_registrar_.reset();
302 user_pref_registrar_.reset();
304 // Unregister content notifications before destroying any components.
305 registrar_.reset();
307 // Unregister a11y status subscription.
308 accessibility_subscription_.reset();
310 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
311 input_method::InputMethodManager::Get()->RemoveObserver(this);
312 ui::ime::InputMethodMenuManager::GetInstance()->RemoveObserver(this);
313 bluetooth_adapter_->RemoveObserver(this);
314 ash::Shell::GetInstance()
315 ->session_state_delegate()
316 ->RemoveSessionStateObserver(this);
317 LoginState::Get()->RemoveObserver(this);
319 if (CrasAudioHandler::IsInitialized())
320 CrasAudioHandler::Get()->RemoveAudioObserver(this);
322 BrowserList::RemoveObserver(this);
323 StopObservingAppWindowRegistry();
324 StopObservingCustodianInfoChanges();
326 policy::BrowserPolicyConnectorChromeOS* connector =
327 g_browser_process->platform_part()->browser_policy_connector_chromeos();
328 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
329 connector->GetDeviceCloudPolicyManager();
330 if (policy_manager)
331 policy_manager->core()->store()->RemoveObserver(this);
333 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
336 // Overridden from ash::SystemTrayDelegate:
337 bool SystemTrayDelegateChromeOS::GetTrayVisibilityOnStartup() {
338 // In case of OOBE / sign in screen tray will be shown later.
339 return LoginState::Get()->IsUserLoggedIn();
342 ash::user::LoginStatus SystemTrayDelegateChromeOS::GetUserLoginStatus() const {
343 // All non-logged in ChromeOS specific LOGGED_IN states map to the same
344 // Ash specific LOGGED_IN state.
345 if (!LoginState::Get()->IsUserLoggedIn())
346 return ash::user::LOGGED_IN_NONE;
348 if (screen_locked_)
349 return ash::user::LOGGED_IN_LOCKED;
351 LoginState::LoggedInUserType user_type =
352 LoginState::Get()->GetLoggedInUserType();
353 switch (user_type) {
354 case LoginState::LOGGED_IN_USER_NONE:
355 return ash::user::LOGGED_IN_NONE;
356 case LoginState::LOGGED_IN_USER_REGULAR:
357 return ash::user::LOGGED_IN_USER;
358 case LoginState::LOGGED_IN_USER_OWNER:
359 return ash::user::LOGGED_IN_OWNER;
360 case LoginState::LOGGED_IN_USER_GUEST:
361 return ash::user::LOGGED_IN_GUEST;
362 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
363 return ash::user::LOGGED_IN_PUBLIC;
364 case LoginState::LOGGED_IN_USER_SUPERVISED:
365 return ash::user::LOGGED_IN_SUPERVISED;
366 case LoginState::LOGGED_IN_USER_KIOSK_APP:
367 return ash::user::LOGGED_IN_KIOSK_APP;
369 NOTREACHED();
370 return ash::user::LOGGED_IN_NONE;
373 void SystemTrayDelegateChromeOS::ChangeProfilePicture() {
374 content::RecordAction(
375 base::UserMetricsAction("OpenChangeProfilePictureDialog"));
376 ShowSettingsSubPageForActiveUser(chrome::kChangeProfilePictureSubPage);
379 const std::string SystemTrayDelegateChromeOS::GetEnterpriseDomain() const {
380 return enterprise_domain_;
383 const base::string16 SystemTrayDelegateChromeOS::GetEnterpriseMessage() const {
384 if (GetEnterpriseDomain().empty())
385 return base::string16();
386 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE,
387 base::UTF8ToUTF16(GetEnterpriseDomain()));
390 const std::string SystemTrayDelegateChromeOS::GetSupervisedUserManager() const {
391 if (!IsUserSupervised())
392 return std::string();
393 return SupervisedUserServiceFactory::GetForProfile(user_profile_)->
394 GetCustodianEmailAddress();
397 const base::string16
398 SystemTrayDelegateChromeOS::GetSupervisedUserManagerName() const {
399 if (!IsUserSupervised())
400 return base::string16();
401 return base::UTF8ToUTF16(SupervisedUserServiceFactory::GetForProfile(
402 user_profile_)->GetCustodianName());
405 const base::string16 SystemTrayDelegateChromeOS::GetSupervisedUserMessage()
406 const {
407 if (!IsUserSupervised())
408 return base::string16();
409 if (IsUserChild())
410 return GetChildUserMessage();
411 return GetLegacySupervisedUserMessage();
414 bool SystemTrayDelegateChromeOS::IsUserSupervised() const {
415 user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser();
416 return user && user->IsSupervised();
419 bool SystemTrayDelegateChromeOS::IsUserChild() const {
420 return user_manager::UserManager::Get()->IsLoggedInAsChildUser();
423 void SystemTrayDelegateChromeOS::GetSystemUpdateInfo(
424 ash::UpdateInfo* info) const {
425 GetUpdateInfo(UpgradeDetector::GetInstance(), info);
428 base::HourClockType SystemTrayDelegateChromeOS::GetHourClockType() const {
429 return clock_type_;
432 void SystemTrayDelegateChromeOS::ShowSettings() {
433 ShowSettingsSubPageForActiveUser("");
436 bool SystemTrayDelegateChromeOS::ShouldShowSettings() {
437 return ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings() &&
438 !ash::Shell::GetInstance()
439 ->session_state_delegate()
440 ->IsInSecondaryLoginScreen();
443 void SystemTrayDelegateChromeOS::ShowDateSettings() {
444 content::RecordAction(base::UserMetricsAction("ShowDateOptions"));
445 std::string sub_page =
446 std::string(chrome::kSearchSubPage) + "#" +
447 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
448 // Everybody can change the time zone (even though it is a device setting).
449 ShowSettingsSubPageForActiveUser(sub_page);
452 void SystemTrayDelegateChromeOS::ShowSetTimeDialog() {
453 SetTimeDialog::ShowDialog(GetNativeWindow());
456 void SystemTrayDelegateChromeOS::ShowNetworkSettingsForGuid(
457 const std::string& guid) {
458 bool userAddingRunning = ash::Shell::GetInstance()
459 ->session_state_delegate()
460 ->IsInSecondaryLoginScreen();
462 if (!LoginState::Get()->IsUserLoggedIn() || userAddingRunning)
463 return;
464 std::string page = chrome::kInternetOptionsSubPage;
465 if (!guid.empty())
466 page += "?guid=" + net::EscapeUrlEncodedData(guid, true);
467 content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog"));
468 ShowSettingsSubPageForActiveUser(page);
471 void SystemTrayDelegateChromeOS::ShowBluetoothSettings() {
472 // TODO(sad): Make this work.
475 void SystemTrayDelegateChromeOS::ShowDisplaySettings() {
476 // TODO(michaelpg): Allow display settings to be shown when they are updated
477 // to work for 3+ displays. See issue 467195.
478 if (ash::Shell::GetInstance()->display_manager()->num_connected_displays() >
479 2) {
480 return;
482 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions"));
483 ShowSettingsSubPageForActiveUser(kDisplaySettingsSubPageName);
486 void SystemTrayDelegateChromeOS::ShowChromeSlow() {
487 chrome::ScopedTabbedBrowserDisplayer displayer(
488 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
489 chrome::ShowSlow(displayer.browser());
492 bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() {
493 // Packaged app is not counted as 'last active', so if a browser opening the
494 // display settings is in background of a packaged app, it will return true.
495 // TODO(mukai): fix this.
496 Browser* active_browser =
497 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH);
498 if (!active_browser)
499 return true;
501 content::WebContents* active_contents =
502 active_browser->tab_strip_model()->GetActiveWebContents();
503 if (!active_contents)
504 return true;
506 GURL visible_url = active_contents->GetLastCommittedURL();
507 GURL display_settings_url =
508 chrome::GetSettingsUrl(kDisplaySettingsSubPageName);
509 GURL display_overscan_url =
510 chrome::GetSettingsUrl(kDisplayOverscanSettingsSubPageName);
511 return (visible_url != display_settings_url &&
512 visible_url != display_overscan_url);
515 void SystemTrayDelegateChromeOS::ShowIMESettings() {
516 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog"));
517 ShowSettingsSubPageForActiveUser(chrome::kLanguageOptionsSubPage);
520 void SystemTrayDelegateChromeOS::ShowHelp() {
521 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(),
522 chrome::HOST_DESKTOP_TYPE_ASH,
523 chrome::HELP_SOURCE_MENU);
526 void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() {
527 chrome::ScopedTabbedBrowserDisplayer displayer(
528 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
529 accessibility::ShowAccessibilityHelp(displayer.browser());
532 void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() {
533 content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings"));
534 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
535 l10n_util::GetStringUTF8(
536 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY);
537 ShowSettingsSubPageForActiveUser(sub_page);
540 void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() {
541 chrome::ScopedTabbedBrowserDisplayer displayer(
542 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
543 chrome::ShowPolicy(displayer.browser());
546 void SystemTrayDelegateChromeOS::ShowSupervisedUserInfo() {
547 // TODO(antrim): find out what should we show in this case.
548 // http://crbug.com/229762
551 void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() {
552 ash::user::LoginStatus status = GetUserLoginStatus();
553 bool userAddingRunning = ash::Shell::GetInstance()
554 ->session_state_delegate()
555 ->IsInSecondaryLoginScreen();
557 if (status == ash::user::LOGGED_IN_NONE ||
558 status == ash::user::LOGGED_IN_LOCKED || userAddingRunning) {
559 scoped_refptr<chromeos::HelpAppLauncher> help_app(
560 new chromeos::HelpAppLauncher(GetNativeWindow()));
561 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE);
562 } else {
563 chrome::ScopedTabbedBrowserDisplayer displayer(
564 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
565 chrome::ShowSingletonTab(displayer.browser(),
566 GURL(chrome::kLearnMoreEnterpriseURL));
570 void SystemTrayDelegateChromeOS::ShowUserLogin() {
571 ash::Shell* shell = ash::Shell::GetInstance();
572 if (!shell->delegate()->IsMultiProfilesEnabled())
573 return;
575 // Only regular non-supervised users could add other users to current session.
576 if (user_manager::UserManager::Get()->GetActiveUser()->GetType() !=
577 user_manager::USER_TYPE_REGULAR) {
578 return;
581 if (static_cast<int>(
582 user_manager::UserManager::Get()->GetLoggedInUsers().size()) >=
583 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers())
584 return;
586 // Launch sign in screen to add another user to current session.
587 if (user_manager::UserManager::Get()
588 ->GetUsersAllowedForMultiProfile()
589 .size()) {
590 // Don't show dialog if any logged in user in multi-profiles session
591 // dismissed it.
592 bool show_intro = true;
593 const user_manager::UserList logged_in_users =
594 user_manager::UserManager::Get()->GetLoggedInUsers();
595 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
596 it != logged_in_users.end();
597 ++it) {
598 show_intro &= !multi_user_util::GetProfileFromUserID(
599 multi_user_util::GetUserIDFromEmail((*it)->email()))
600 ->GetPrefs()
601 ->GetBoolean(prefs::kMultiProfileNeverShowIntro);
602 if (!show_intro)
603 break;
605 if (show_intro) {
606 base::Callback<void(bool)> on_accept =
607 base::Bind(&OnAcceptMultiprofilesIntro);
608 ShowMultiprofilesIntroDialog(on_accept);
609 } else {
610 UserAddingScreen::Get()->Start();
615 void SystemTrayDelegateChromeOS::SignOut() {
616 chrome::AttemptUserExit();
619 void SystemTrayDelegateChromeOS::RequestLockScreen() {
620 // TODO(antrim) : additional logging for crbug/173178
621 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate";
622 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
625 void SystemTrayDelegateChromeOS::RequestRestartForUpdate() {
626 // We expect that UpdateEngine is in "Reboot for update" state now.
627 chrome::NotifyAndTerminate(true /* fast path */);
630 void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices(
631 ash::BluetoothDeviceList* list) {
632 device::BluetoothAdapter::DeviceList devices =
633 bluetooth_adapter_->GetDevices();
634 for (size_t i = 0; i < devices.size(); ++i) {
635 device::BluetoothDevice* device = devices[i];
636 ash::BluetoothDeviceInfo info;
637 info.address = device->GetAddress();
638 info.display_name = device->GetName();
639 info.connected = device->IsConnected();
640 info.connecting = device->IsConnecting();
641 info.paired = device->IsPaired();
642 list->push_back(info);
646 void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() {
647 if (GetBluetoothDiscovering()) {
648 LOG(WARNING) << "Already have active Bluetooth device discovery session.";
649 return;
651 VLOG(1) << "Requesting new Bluetooth device discovery session.";
652 should_run_bluetooth_discovery_ = true;
653 bluetooth_adapter_->StartDiscoverySession(
654 base::Bind(&SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession,
655 weak_ptr_factory_.GetWeakPtr()),
656 base::Bind(&BluetoothSetDiscoveringError));
659 void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() {
660 should_run_bluetooth_discovery_ = false;
661 if (!GetBluetoothDiscovering()) {
662 LOG(WARNING) << "No active Bluetooth device discovery session.";
663 return;
665 VLOG(1) << "Stopping Bluetooth device discovery session.";
666 bluetooth_discovery_session_->Stop(
667 base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError));
670 void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice(
671 const std::string& address) {
672 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
673 if (!device || device->IsConnecting() ||
674 (device->IsConnected() && device->IsPaired())) {
675 return;
677 if (device->IsPaired() && !device->IsConnectable())
678 return;
679 if (device->IsPaired() || !device->IsPairable()) {
680 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
681 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE);
682 device->Connect(NULL,
683 base::Bind(&base::DoNothing),
684 base::Bind(&BluetoothDeviceConnectError));
685 } else { // Show paring dialog for the unpaired device.
686 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
687 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE);
688 BluetoothPairingDialog* dialog =
689 new BluetoothPairingDialog(GetNativeWindow(), device);
690 // The dialog deletes itself on close.
691 dialog->Show();
695 bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() {
696 return bluetooth_adapter_->IsDiscovering();
699 void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) {
700 input_method::InputMethodManager* manager =
701 input_method::InputMethodManager::Get();
702 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
703 input_method::InputMethodDescriptor ime =
704 manager->GetActiveIMEState()->GetCurrentInputMethod();
705 ExtractIMEInfo(ime, *util, info);
706 info->selected = true;
709 void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) {
710 input_method::InputMethodManager* manager =
711 input_method::InputMethodManager::Get();
712 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
713 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors(
714 manager->GetActiveIMEState()->GetActiveInputMethods());
715 std::string current =
716 manager->GetActiveIMEState()->GetCurrentInputMethod().id();
717 for (size_t i = 0; i < ime_descriptors->size(); i++) {
718 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i);
719 ash::IMEInfo info;
720 ExtractIMEInfo(ime, *util, &info);
721 info.selected = ime.id() == current;
722 list->push_back(info);
726 void SystemTrayDelegateChromeOS::GetCurrentIMEProperties(
727 ash::IMEPropertyInfoList* list) {
728 ui::ime::InputMethodMenuItemList menu_list =
729 ui::ime::InputMethodMenuManager::GetInstance()->
730 GetCurrentInputMethodMenuItemList();
731 for (size_t i = 0; i < menu_list.size(); ++i) {
732 ash::IMEPropertyInfo property;
733 property.key = menu_list[i].key;
734 property.name = base::UTF8ToUTF16(menu_list[i].label);
735 property.selected = menu_list[i].is_selection_item_checked;
736 list->push_back(property);
740 void SystemTrayDelegateChromeOS::SwitchIME(const std::string& ime_id) {
741 input_method::InputMethodManager::Get()
742 ->GetActiveIMEState()
743 ->ChangeInputMethod(ime_id, false /* show_message */);
744 input_method::InputMethodSwitchRecorder::Get()->RecordSwitch(
745 true /* by_tray_menu */);
748 void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string& key) {
749 input_method::InputMethodManager::Get()->ActivateInputMethodMenuItem(key);
752 void SystemTrayDelegateChromeOS::ManageBluetoothDevices() {
753 content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage"));
754 std::string sub_page =
755 std::string(chrome::kSearchSubPage) + "#" +
756 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH);
757 ShowSettingsSubPageForActiveUser(sub_page);
760 void SystemTrayDelegateChromeOS::ToggleBluetooth() {
761 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(),
762 base::Bind(&base::DoNothing),
763 base::Bind(&BluetoothPowerFailure));
766 void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog(
767 const std::string& type) {
768 if (type == shill::kTypeCellular) {
769 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
770 return;
772 NetworkConfigView::ShowForType(type, GetNativeWindow());
775 bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() {
776 return bluetooth_adapter_->IsPresent();
779 bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() {
780 return bluetooth_adapter_->IsPowered();
783 bool SystemTrayDelegateChromeOS::GetBluetoothDiscovering() {
784 return (bluetooth_discovery_session_.get() &&
785 bluetooth_discovery_session_->IsActive());
788 void SystemTrayDelegateChromeOS::ChangeProxySettings() {
789 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE);
790 LoginDisplayHostImpl::default_host()->OpenProxySettings();
793 ash::CastConfigDelegate* SystemTrayDelegateChromeOS::GetCastConfigDelegate()
794 const {
795 return cast_config_delegate_.get();
798 ash::NetworkingConfigDelegate*
799 SystemTrayDelegateChromeOS::GetNetworkingConfigDelegate() const {
800 return networking_config_delegate_.get();
803 ash::VolumeControlDelegate*
804 SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const {
805 return volume_control_delegate_.get();
808 void SystemTrayDelegateChromeOS::SetVolumeControlDelegate(
809 scoped_ptr<ash::VolumeControlDelegate> delegate) {
810 volume_control_delegate_.swap(delegate);
813 bool SystemTrayDelegateChromeOS::GetSessionStartTime(
814 base::TimeTicks* session_start_time) {
815 *session_start_time = session_start_time_;
816 return have_session_start_time_;
819 bool SystemTrayDelegateChromeOS::GetSessionLengthLimit(
820 base::TimeDelta* session_length_limit) {
821 *session_length_limit = session_length_limit_;
822 return have_session_length_limit_;
825 int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() {
826 return l10n_util::GetLocalizedContentsWidthInPixels(
827 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS);
830 void SystemTrayDelegateChromeOS::ActiveUserWasChanged() {
831 SetProfile(ProfileManager::GetActiveUserProfile());
832 GetSystemTrayNotifier()->NotifyUserUpdate();
835 bool SystemTrayDelegateChromeOS::IsSearchKeyMappedToCapsLock() {
836 return search_key_mapped_to_ == input_method::kCapsLockKey;
839 ash::tray::UserAccountsDelegate*
840 SystemTrayDelegateChromeOS::GetUserAccountsDelegate(
841 const std::string& user_id) {
842 if (!accounts_delegates_.contains(user_id)) {
843 const user_manager::User* user =
844 user_manager::UserManager::Get()->FindUser(user_id);
845 Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
846 CHECK(user_profile);
847 accounts_delegates_.set(
848 user_id,
849 scoped_ptr<ash::tray::UserAccountsDelegate>(
850 new UserAccountsDelegateChromeOS(user_profile)));
852 return accounts_delegates_.get(user_id);
855 void SystemTrayDelegateChromeOS::AddCustodianInfoTrayObserver(
856 ash::CustodianInfoTrayObserver* observer) {
857 custodian_info_changed_observers_.AddObserver(observer);
860 void SystemTrayDelegateChromeOS::RemoveCustodianInfoTrayObserver(
861 ash::CustodianInfoTrayObserver* observer) {
862 custodian_info_changed_observers_.RemoveObserver(observer);
865 void SystemTrayDelegateChromeOS::AddShutdownPolicyObserver(
866 ash::ShutdownPolicyObserver* observer) {
867 shutdown_policy_observers_.AddObserver(observer);
870 void SystemTrayDelegateChromeOS::RemoveShutdownPolicyObserver(
871 ash::ShutdownPolicyObserver* observer) {
872 shutdown_policy_observers_.RemoveObserver(observer);
875 void SystemTrayDelegateChromeOS::ShouldRebootOnShutdown(
876 const ash::RebootOnShutdownCallback& callback) {
877 shutdown_policy_handler_->CheckIfRebootOnShutdown(callback);
880 ash::VPNDelegate* SystemTrayDelegateChromeOS::GetVPNDelegate() const {
881 return vpn_delegate_.get();
884 void SystemTrayDelegateChromeOS::UserAddedToSession(
885 const user_manager::User* active_user) {
888 void SystemTrayDelegateChromeOS::ActiveUserChanged(
889 const user_manager::User* /* active_user */) {
892 void SystemTrayDelegateChromeOS::UserChangedChildStatus(
893 user_manager::User* user) {
894 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(user);
896 // Returned user_profile might be NULL on restoring Users on browser start.
897 // At some point profile is not yet fully initiated.
898 if (session_started_ &&
899 user_profile != NULL &&
900 user_profile_ == user_profile) {
901 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
902 GetUserLoginStatus());
906 ash::SystemTray* SystemTrayDelegateChromeOS::GetPrimarySystemTray() {
907 return ash::Shell::GetInstance()->GetPrimarySystemTray();
910 ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() {
911 return ash::Shell::GetInstance()->system_tray_notifier();
914 void SystemTrayDelegateChromeOS::SetProfile(Profile* profile) {
915 // Stop observing the AppWindowRegistry of the current |user_profile_|.
916 StopObservingAppWindowRegistry();
918 // Stop observing custodian info changes of the current |user_profile_|.
919 StopObservingCustodianInfoChanges();
921 user_profile_ = profile;
923 // Start observing the AppWindowRegistry of the newly set |user_profile_|.
924 extensions::AppWindowRegistry::Get(user_profile_)->AddObserver(this);
926 // Start observing custodian info changes of the newly set |user_profile_|.
927 SupervisedUserServiceFactory::GetForProfile(profile)->AddObserver(this);
929 PrefService* prefs = profile->GetPrefs();
930 user_pref_registrar_.reset(new PrefChangeRegistrar);
931 user_pref_registrar_->Init(prefs);
932 user_pref_registrar_->Add(
933 prefs::kUse24HourClock,
934 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType,
935 base::Unretained(this)));
936 user_pref_registrar_->Add(
937 prefs::kLanguageRemapSearchKeyTo,
938 base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged,
939 base::Unretained(this)));
940 user_pref_registrar_->Add(
941 prefs::kShowLogoutButtonInTray,
942 base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray,
943 base::Unretained(this)));
944 user_pref_registrar_->Add(
945 prefs::kLogoutDialogDurationMs,
946 base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration,
947 base::Unretained(this)));
948 user_pref_registrar_->Add(
949 prefs::kAccessibilityLargeCursorEnabled,
950 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
951 base::Unretained(this),
952 ui::A11Y_NOTIFICATION_NONE));
953 user_pref_registrar_->Add(
954 prefs::kAccessibilityAutoclickEnabled,
955 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
956 base::Unretained(this),
957 ui::A11Y_NOTIFICATION_NONE));
958 user_pref_registrar_->Add(
959 prefs::kShouldAlwaysShowAccessibilityMenu,
960 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged,
961 base::Unretained(this),
962 ui::A11Y_NOTIFICATION_NONE));
963 user_pref_registrar_->Add(
964 prefs::kPerformanceTracingEnabled,
965 base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing,
966 base::Unretained(this)));
968 UpdateShowLogoutButtonInTray();
969 UpdateLogoutDialogDuration();
970 UpdatePerformanceTracing();
971 OnCustodianInfoChanged();
972 search_key_mapped_to_ =
973 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo);
976 bool SystemTrayDelegateChromeOS::UnsetProfile(Profile* profile) {
977 if (profile != user_profile_)
978 return false;
979 user_pref_registrar_.reset();
980 user_profile_ = NULL;
981 return true;
984 bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const {
985 return ShouldUse24HourClock();
988 bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const {
989 // On login screen and in guest mode owner default is used for
990 // kUse24HourClock preference.
991 const ash::user::LoginStatus status = GetUserLoginStatus();
992 const CrosSettings* const cros_settings = CrosSettings::Get();
993 bool system_use_24_hour_clock = true;
994 const bool system_value_found = cros_settings->GetBoolean(
995 kSystemUse24HourClock, &system_use_24_hour_clock);
997 if ((status == ash::user::LOGGED_IN_NONE) || !user_pref_registrar_)
998 return (system_value_found
999 ? system_use_24_hour_clock
1000 : (base::GetHourClockType() == base::k24HourClock));
1002 const PrefService::Preference* user_pref =
1003 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock);
1004 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue())
1005 return (system_value_found
1006 ? system_use_24_hour_clock
1007 : (base::GetHourClockType() == base::k24HourClock));
1009 user_manager::User* active_user =
1010 user_manager::UserManager::Get()->GetActiveUser();
1011 if (active_user) {
1012 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(active_user);
1013 if (user_profile) {
1014 user_pref =
1015 user_profile->GetPrefs()->FindPreference(prefs::kUse24HourClock);
1019 bool use_24_hour_clock = true;
1020 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock);
1021 return use_24_hour_clock;
1024 void SystemTrayDelegateChromeOS::UpdateClockType() {
1025 const bool use_24_hour_clock = ShouldUse24HourClock();
1026 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock;
1027 GetSystemTrayNotifier()->NotifyDateFormatChanged();
1028 // This also works for enterprise-managed devices because they never have
1029 // local owner.
1030 if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
1031 user_manager::User* const user =
1032 user_manager::UserManager::Get()->GetActiveUser();
1033 CHECK(user);
1034 Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user);
1035 CHECK(profile);
1036 OwnerSettingsServiceChromeOS* const service =
1037 OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
1038 CHECK(service);
1039 service->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
1043 void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() {
1044 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
1045 user_pref_registrar_->prefs()->GetBoolean(
1046 prefs::kShowLogoutButtonInTray));
1049 void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() {
1050 const int duration_ms =
1051 user_pref_registrar_->prefs()->GetInteger(prefs::kLogoutDialogDurationMs);
1052 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged(
1053 base::TimeDelta::FromMilliseconds(duration_ms));
1056 void SystemTrayDelegateChromeOS::UpdateSessionStartTime() {
1057 const PrefService* local_state = local_state_registrar_->prefs();
1058 if (local_state->HasPrefPath(prefs::kSessionStartTime)) {
1059 have_session_start_time_ = true;
1060 session_start_time_ = base::TimeTicks::FromInternalValue(
1061 local_state->GetInt64(prefs::kSessionStartTime));
1062 } else {
1063 have_session_start_time_ = false;
1064 session_start_time_ = base::TimeTicks();
1066 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
1069 void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() {
1070 const PrefService* local_state = local_state_registrar_->prefs();
1071 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) {
1072 have_session_length_limit_ = true;
1073 session_length_limit_ = base::TimeDelta::FromMilliseconds(
1074 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit),
1075 kSessionLengthLimitMinMs),
1076 kSessionLengthLimitMaxMs));
1077 } else {
1078 have_session_length_limit_ = false;
1079 session_length_limit_ = base::TimeDelta();
1081 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
1084 void SystemTrayDelegateChromeOS::StopObservingAppWindowRegistry() {
1085 if (!user_profile_)
1086 return;
1088 extensions::AppWindowRegistry* registry =
1089 extensions::AppWindowRegistry::Factory::GetForBrowserContext(
1090 user_profile_, false);
1091 if (registry)
1092 registry->RemoveObserver(this);
1095 void SystemTrayDelegateChromeOS::StopObservingCustodianInfoChanges() {
1096 if (!user_profile_)
1097 return;
1099 SupervisedUserService* service = SupervisedUserServiceFactory::GetForProfile(
1100 user_profile_);
1101 if (service)
1102 service->RemoveObserver(this);
1105 void SystemTrayDelegateChromeOS::NotifyIfLastWindowClosed() {
1106 if (!user_profile_)
1107 return;
1109 BrowserList* browser_list =
1110 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
1111 for (BrowserList::const_iterator it = browser_list->begin();
1112 it != browser_list->end();
1113 ++it) {
1114 if ((*it)->profile()->IsSameProfile(user_profile_)) {
1115 // The current user has at least one open browser window.
1116 return;
1120 if (!extensions::AppWindowRegistry::Get(
1121 user_profile_)->app_windows().empty()) {
1122 // The current user has at least one open app window.
1123 return;
1126 GetSystemTrayNotifier()->NotifyLastWindowClosed();
1129 // LoginState::Observer overrides.
1130 void SystemTrayDelegateChromeOS::LoggedInStateChanged() {
1131 // It apparently sometimes takes a while after login before the current user
1132 // is recognized as the owner. Make sure that the system-wide clock setting
1133 // is updated when the recognition eventually happens
1134 // (http://crbug.com/278601).
1136 // Note that it isn't safe to blindly call UpdateClockType() from this
1137 // method, as LoggedInStateChanged() is also called before the logged-in
1138 // user's profile has actually been loaded (http://crbug.com/317745). The
1139 // system tray's time format is updated at login via SetProfile().
1140 if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
1141 user_manager::User* const user =
1142 user_manager::UserManager::Get()->GetActiveUser();
1143 CHECK(user);
1144 Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user);
1145 CHECK(profile);
1146 OwnerSettingsServiceChromeOS* const service =
1147 OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
1148 CHECK(service);
1149 service->SetBoolean(kSystemUse24HourClock, ShouldUse24HourClock());
1153 // Overridden from SessionManagerClient::Observer.
1154 void SystemTrayDelegateChromeOS::ScreenIsLocked() {
1155 screen_locked_ = true;
1156 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1159 void SystemTrayDelegateChromeOS::ScreenIsUnlocked() {
1160 screen_locked_ = false;
1161 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
1164 gfx::NativeWindow SystemTrayDelegateChromeOS::GetNativeWindow() const {
1165 bool session_started = ash::Shell::GetInstance()
1166 ->session_state_delegate()
1167 ->IsActiveUserSessionStarted();
1168 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started);
1171 // content::NotificationObserver implementation.
1172 void SystemTrayDelegateChromeOS::Observe(
1173 int type,
1174 const content::NotificationSource& source,
1175 const content::NotificationDetails& details) {
1176 switch (type) {
1177 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
1178 UpdateClockType();
1179 break;
1181 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
1182 ash::UpdateInfo info;
1183 GetUpdateInfo(content::Source<UpgradeDetector>(source).ptr(), &info);
1184 GetSystemTrayNotifier()->NotifyUpdateRecommended(info);
1185 break;
1187 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
1188 // This notification is also sent on login screen when user avatar
1189 // is loaded from file.
1190 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) {
1191 GetSystemTrayNotifier()->NotifyUserUpdate();
1193 break;
1195 case chrome::NOTIFICATION_PROFILE_CREATED: {
1196 SetProfile(content::Source<Profile>(source).ptr());
1197 registrar_->Remove(this,
1198 chrome::NOTIFICATION_PROFILE_CREATED,
1199 content::NotificationService::AllSources());
1200 break;
1202 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1203 if (UnsetProfile(content::Source<Profile>(source).ptr())) {
1204 registrar_->Remove(this,
1205 chrome::NOTIFICATION_PROFILE_DESTROYED,
1206 content::NotificationService::AllSources());
1208 break;
1210 case chrome::NOTIFICATION_SESSION_STARTED: {
1211 session_started_ = true;
1212 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1213 GetUserLoginStatus());
1214 SetProfile(ProfileManager::GetActiveUserProfile());
1215 break;
1217 default:
1218 NOTREACHED();
1222 void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() {
1223 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger(
1224 prefs::kLanguageRemapSearchKeyTo);
1227 void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged(
1228 ui::AccessibilityNotificationVisibility notify) {
1229 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify);
1232 void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() {
1233 if (!user_pref_registrar_)
1234 return;
1235 bool value = user_pref_registrar_->prefs()->GetBoolean(
1236 prefs::kPerformanceTracingEnabled);
1237 GetSystemTrayNotifier()->NotifyTracingModeChanged(value);
1240 // Overridden from InputMethodManager::Observer.
1241 void SystemTrayDelegateChromeOS::InputMethodChanged(
1242 input_method::InputMethodManager* manager,
1243 Profile* /* profile */,
1244 bool show_message) {
1245 GetSystemTrayNotifier()->NotifyRefreshIME();
1248 // Overridden from InputMethodMenuManager::Observer.
1249 void SystemTrayDelegateChromeOS::InputMethodMenuItemChanged(
1250 ui::ime::InputMethodMenuManager* manager) {
1251 GetSystemTrayNotifier()->NotifyRefreshIME();
1254 // Overridden from CrasAudioHandler::AudioObserver.
1255 void SystemTrayDelegateChromeOS::OnOutputNodeVolumeChanged(uint64_t node_id,
1256 int volume) {
1257 GetSystemTrayNotifier()->NotifyAudioOutputVolumeChanged(node_id, volume);
1260 void SystemTrayDelegateChromeOS::OnOutputMuteChanged(bool mute_on) {
1261 GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged(mute_on);
1264 void SystemTrayDelegateChromeOS::OnInputNodeGainChanged(uint64_t /* node_id */,
1265 int /* gain */) {
1268 void SystemTrayDelegateChromeOS::OnInputMuteChanged(bool /* mute_on */) {
1271 void SystemTrayDelegateChromeOS::OnAudioNodesChanged() {
1272 GetSystemTrayNotifier()->NotifyAudioNodesChanged();
1275 void SystemTrayDelegateChromeOS::OnActiveOutputNodeChanged() {
1276 GetSystemTrayNotifier()->NotifyAudioActiveOutputNodeChanged();
1279 void SystemTrayDelegateChromeOS::OnActiveInputNodeChanged() {
1280 GetSystemTrayNotifier()->NotifyAudioActiveInputNodeChanged();
1283 // Overridden from BluetoothAdapter::Observer.
1284 void SystemTrayDelegateChromeOS::AdapterPresentChanged(
1285 device::BluetoothAdapter* adapter,
1286 bool present) {
1287 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1290 void SystemTrayDelegateChromeOS::AdapterPoweredChanged(
1291 device::BluetoothAdapter* adapter,
1292 bool powered) {
1293 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1296 void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged(
1297 device::BluetoothAdapter* adapter,
1298 bool discovering) {
1299 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1302 void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter* adapter,
1303 device::BluetoothDevice* device) {
1304 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1307 void SystemTrayDelegateChromeOS::DeviceChanged(
1308 device::BluetoothAdapter* adapter,
1309 device::BluetoothDevice* device) {
1310 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1313 void SystemTrayDelegateChromeOS::DeviceRemoved(
1314 device::BluetoothAdapter* adapter,
1315 device::BluetoothDevice* device) {
1316 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1319 void SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession(
1320 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
1321 // If the discovery session was returned after a request to stop discovery
1322 // (e.g. the user dismissed the Bluetooth detailed view before the call
1323 // returned), don't claim the discovery session and let it clean up.
1324 if (!should_run_bluetooth_discovery_)
1325 return;
1326 VLOG(1) << "Claiming new Bluetooth device discovery session.";
1327 bluetooth_discovery_session_ = discovery_session.Pass();
1328 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1331 void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() {
1332 policy::BrowserPolicyConnectorChromeOS* connector =
1333 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1334 std::string enterprise_domain = connector->GetEnterpriseDomain();
1335 if (enterprise_domain_ != enterprise_domain) {
1336 enterprise_domain_ = enterprise_domain;
1337 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1341 // Overridden from CloudPolicyStore::Observer
1342 void SystemTrayDelegateChromeOS::OnStoreLoaded(
1343 policy::CloudPolicyStore* store) {
1344 UpdateEnterpriseDomain();
1347 void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore* store) {
1348 UpdateEnterpriseDomain();
1351 // Overridden from ash::SessionStateObserver
1352 void SystemTrayDelegateChromeOS::UserAddedToSession(
1353 const std::string& user_id) {
1354 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1357 void SystemTrayDelegateChromeOS::ActiveUserChanged(
1358 const std::string& /* user_id */) {
1359 UpdateClockType();
1362 // Overridden from chrome::BrowserListObserver.
1363 void SystemTrayDelegateChromeOS::OnBrowserRemoved(Browser* browser) {
1364 NotifyIfLastWindowClosed();
1367 // Overridden from extensions::AppWindowRegistry::Observer.
1368 void SystemTrayDelegateChromeOS::OnAppWindowRemoved(
1369 extensions::AppWindow* app_window) {
1370 NotifyIfLastWindowClosed();
1373 // Overridden from SupervisedUserServiceObserver.
1374 void SystemTrayDelegateChromeOS::OnCustodianInfoChanged() {
1375 FOR_EACH_OBSERVER(
1376 ash::CustodianInfoTrayObserver, custodian_info_changed_observers_,
1377 OnCustodianInfoChanged());
1380 void SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged(
1381 const AccessibilityStatusEventDetails& details) {
1382 if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN)
1383 accessibility_subscription_.reset();
1384 else
1385 OnAccessibilityModeChanged(details.notify);
1388 void SystemTrayDelegateChromeOS::OnShutdownPolicyChanged(
1389 bool reboot_on_shutdown) {
1390 // Notify all observers.
1391 FOR_EACH_OBSERVER(ash::ShutdownPolicyObserver, shutdown_policy_observers_,
1392 OnShutdownPolicyChanged(reboot_on_shutdown));
1395 const base::string16
1396 SystemTrayDelegateChromeOS::GetLegacySupervisedUserMessage() const {
1397 std::string user_manager_name = GetSupervisedUserManager();
1398 return l10n_util::GetStringFUTF16(
1399 IDS_USER_IS_SUPERVISED_BY_NOTICE,
1400 base::UTF8ToUTF16(user_manager_name));
1403 const base::string16
1404 SystemTrayDelegateChromeOS::GetChildUserMessage() const {
1405 #if defined(ENABLE_SUPERVISED_USERS)
1406 SupervisedUserService* service =
1407 SupervisedUserServiceFactory::GetForProfile(user_profile_);
1408 base::string16 first_custodian =
1409 base::UTF8ToUTF16(service->GetCustodianEmailAddress());
1410 base::string16 second_custodian =
1411 base::UTF8ToUTF16(service->GetSecondCustodianEmailAddress());
1412 LOG_IF(WARNING, first_custodian.empty()) <<
1413 "Returning incomplete child user message as manager not known yet.";
1414 if (second_custodian.empty()) {
1415 return l10n_util::GetStringFUTF16(
1416 IDS_CHILD_USER_IS_MANAGED_BY_ONE_PARENT_NOTICE, first_custodian);
1417 } else {
1418 return l10n_util::GetStringFUTF16(
1419 IDS_CHILD_USER_IS_MANAGED_BY_TWO_PARENTS_NOTICE,
1420 first_custodian,
1421 second_custodian);
1423 #endif
1425 LOG(WARNING) << "SystemTrayDelegateChromeOS::GetChildUserMessage call while "
1426 << "ENABLE_SUPERVISED_USERS undefined.";
1427 return base::string16();
1430 ash::SystemTrayDelegate* CreateSystemTrayDelegate() {
1431 return new SystemTrayDelegateChromeOS();
1434 } // namespace chromeos