1 // Copyright (c) 2012 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/chromeos/system/ash_system_tray_delegate.h"
12 #include "ash/ash_switches.h"
13 #include "ash/desktop_background/desktop_background_controller.h"
14 #include "ash/session_state_delegate.h"
15 #include "ash/session_state_observer.h"
16 #include "ash/shell.h"
17 #include "ash/shell_delegate.h"
18 #include "ash/shell_window_ids.h"
19 #include "ash/system/bluetooth/bluetooth_observer.h"
20 #include "ash/system/date/clock_observer.h"
21 #include "ash/system/drive/drive_observer.h"
22 #include "ash/system/ime/ime_observer.h"
23 #include "ash/system/logout_button/logout_button_observer.h"
24 #include "ash/system/tray/system_tray.h"
25 #include "ash/system/tray/system_tray_delegate.h"
26 #include "ash/system/tray/system_tray_notifier.h"
27 #include "ash/system/tray_accessibility.h"
28 #include "ash/system/tray_caps_lock.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/command_line.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/choose_mobile_network_dialog.h"
50 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
51 #include "chrome/browser/chromeos/drive/job_list.h"
52 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
53 #include "chrome/browser/chromeos/input_method/input_method_util.h"
54 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
55 #include "chrome/browser/chromeos/login/help_app_launcher.h"
56 #include "chrome/browser/chromeos/login/login_display_host.h"
57 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
58 #include "chrome/browser/chromeos/login/login_wizard.h"
59 #include "chrome/browser/chromeos/login/startup_utils.h"
60 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
61 #include "chrome/browser/chromeos/login/user.h"
62 #include "chrome/browser/chromeos/login/user_adding_screen.h"
63 #include "chrome/browser/chromeos/login/user_manager.h"
64 #include "chrome/browser/chromeos/options/network_config_view.h"
65 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
66 #include "chrome/browser/chromeos/settings/cros_settings.h"
67 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
68 #include "chrome/browser/chromeos/system_key_event_listener.h"
69 #include "chrome/browser/drive/drive_service_interface.h"
70 #include "chrome/browser/feedback/tracing_manager.h"
71 #include "chrome/browser/google/google_util.h"
72 #include "chrome/browser/lifetime/application_lifetime.h"
73 #include "chrome/browser/policy/browser_policy_connector.h"
74 #include "chrome/browser/policy/cloud/cloud_policy_store.h"
75 #include "chrome/browser/profiles/profile_manager.h"
76 #include "chrome/browser/ui/ash/volume_controller_chromeos.h"
77 #include "chrome/browser/ui/browser.h"
78 #include "chrome/browser/ui/browser_finder.h"
79 #include "chrome/browser/ui/chrome_pages.h"
80 #include "chrome/browser/ui/host_desktop.h"
81 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
82 #include "chrome/browser/ui/singleton_tabs.h"
83 #include "chrome/browser/ui/tabs/tab_strip_model.h"
84 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
85 #include "chrome/browser/upgrade_detector.h"
86 #include "chrome/common/pref_names.h"
87 #include "chrome/common/url_constants.h"
88 #include "chromeos/dbus/dbus_thread_manager.h"
89 #include "chromeos/dbus/session_manager_client.h"
90 #include "chromeos/ime/extension_ime_util.h"
91 #include "chromeos/ime/input_method_manager.h"
92 #include "chromeos/ime/xkeyboard.h"
93 #include "chromeos/login/login_state.h"
94 #include "content/public/browser/browser_thread.h"
95 #include "content/public/browser/notification_observer.h"
96 #include "content/public/browser/notification_service.h"
97 #include "content/public/browser/user_metrics.h"
98 #include "content/public/browser/web_contents.h"
99 #include "device/bluetooth/bluetooth_adapter.h"
100 #include "device/bluetooth/bluetooth_adapter_factory.h"
101 #include "device/bluetooth/bluetooth_device.h"
102 #include "grit/ash_strings.h"
103 #include "grit/generated_resources.h"
104 #include "grit/locale_settings.h"
105 #include "net/base/escape.h"
106 #include "third_party/cros_system_api/dbus/service_constants.h"
107 #include "ui/base/l10n/l10n_util.h"
108 #include "ui/base/l10n/time_format.h"
110 using drive::DriveIntegrationService;
111 using drive::DriveIntegrationServiceFactory;
117 // The minimum session length limit that can be set.
118 const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
120 // The maximum session length limit that can be set.
121 const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
123 const char kDisplaySettingsSubPageName[] = "display";
124 const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan";
126 void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
127 const input_method::InputMethodUtil& util,
128 ash::IMEInfo* info) {
130 info->name = util.GetInputMethodLongName(ime);
131 info->medium_name = util.GetInputMethodMediumName(ime);
132 info->short_name = util.GetInputMethodShortName(ime);
133 info->third_party = extension_ime_util::IsExtensionIME(ime.id());
136 gfx::NativeWindow GetNativeWindowByStatus(
137 ash::user::LoginStatus login_status,
138 bool session_started) {
141 login_status == ash::user::LOGGED_IN_NONE ||
142 login_status == ash::user::LOGGED_IN_LOCKED) ?
143 ash::internal::kShellWindowId_LockSystemModalContainer :
144 ash::internal::kShellWindowId_SystemModalContainer;
145 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
149 // Converts drive::JobInfo to ash::DriveOperationStatus.
150 // If the job is not of type that ash tray is interested, returns false.
151 bool ConvertToDriveOperationStatus(const drive::JobInfo& info,
152 ash::DriveOperationStatus* status) {
153 if (info.job_type == drive::TYPE_DOWNLOAD_FILE) {
154 status->type = ash::DriveOperationStatus::OPERATION_DOWNLOAD;
155 } else if (info.job_type == drive::TYPE_UPLOAD_NEW_FILE ||
156 info.job_type == drive::TYPE_UPLOAD_EXISTING_FILE) {
157 status->type = ash::DriveOperationStatus::OPERATION_UPLOAD;
162 if (info.state == drive::STATE_NONE)
163 status->state = ash::DriveOperationStatus::OPERATION_NOT_STARTED;
165 status->state = ash::DriveOperationStatus::OPERATION_IN_PROGRESS;
167 status->id = info.job_id;
168 status->file_path = info.file_path;
169 status->progress = info.num_total_bytes == 0 ? 0.0 :
170 static_cast<double>(info.num_completed_bytes) /
171 static_cast<double>(info.num_total_bytes);
175 // Converts drive::JobInfo that has finished in |error| state
176 // to ash::DriveOperationStatus.
177 // If the job is not of type that ash tray is interested, returns false.
178 bool ConvertToFinishedDriveOperationStatus(const drive::JobInfo& info,
179 drive::FileError error,
180 ash::DriveOperationStatus* status) {
181 if (!ConvertToDriveOperationStatus(info, status))
183 status->state = (error == drive::FILE_ERROR_OK) ?
184 ash::DriveOperationStatus::OPERATION_COMPLETED :
185 ash::DriveOperationStatus::OPERATION_FAILED;
189 // Converts a list of drive::JobInfo to a list of ash::DriveOperationStatusList.
190 ash::DriveOperationStatusList ConvertToDriveStatusList(
191 const std::vector<drive::JobInfo>& list) {
192 ash::DriveOperationStatusList results;
193 for (size_t i = 0; i < list.size(); ++i) {
194 ash::DriveOperationStatus status;
195 if (ConvertToDriveOperationStatus(list[i], &status))
196 results.push_back(status);
201 void BluetoothPowerFailure() {
202 // TODO(sad): Show an error bubble?
205 void BluetoothDiscoveryFailure() {
206 // TODO(sad): Show an error bubble?
209 void BluetoothSetDiscoveringError() {
210 LOG(ERROR) << "BluetoothSetDiscovering failed.";
213 void BluetoothDeviceConnectError(
214 device::BluetoothDevice::ConnectErrorCode error_code) {
215 // TODO(sad): Do something?
218 // Shows the settings sub page in the last active browser. If there is no such
219 // browser, creates a new browser with the settings sub page.
220 void ShowSettingsSubPageForAppropriateBrowser(const std::string& sub_page) {
221 chrome::ScopedTabbedBrowserDisplayer displayer(
222 ProfileManager::GetDefaultProfileOrOffTheRecord(),
223 chrome::HOST_DESKTOP_TYPE_ASH);
224 chrome::ShowSettingsSubPage(displayer.browser(), sub_page);
227 void ShowNetworkSettingsPage(const std::string& service_path) {
228 std::string page = chrome::kInternetOptionsSubPage;
229 page += "?servicePath=" + net::EscapeUrlEncodedData(service_path, true);
230 content::RecordAction(
231 content::UserMetricsAction("OpenInternetOptionsDialog"));
232 ShowSettingsSubPageForAppropriateBrowser(page);
235 class SystemTrayDelegate : public ash::SystemTrayDelegate,
236 public SessionManagerClient::Observer,
237 public drive::JobListObserver,
238 public content::NotificationObserver,
239 public input_method::InputMethodManager::Observer,
240 public chromeos::LoginState::Observer,
241 public device::BluetoothAdapter::Observer,
242 public SystemKeyEventListener::CapsLockObserver,
243 public policy::CloudPolicyStore::Observer,
244 public ash::SessionStateObserver {
247 : ui_weak_ptr_factory_(
248 new base::WeakPtrFactory<SystemTrayDelegate>(this)),
250 clock_type_(base::GetHourClockType()),
251 search_key_mapped_to_(input_method::kSearchKey),
252 screen_locked_(false),
253 have_session_start_time_(false),
254 have_session_length_limit_(false),
255 volume_control_delegate_(new VolumeController()) {
256 // Register notifications on construction so that events such as
257 // PROFILE_CREATED do not get missed if they happen before Initialize().
258 registrar_.reset(new content::NotificationRegistrar);
259 registrar_->Add(this,
260 chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
261 content::NotificationService::AllSources());
262 registrar_->Add(this,
263 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
264 content::NotificationService::AllSources());
265 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) {
266 registrar_->Add(this,
267 chrome::NOTIFICATION_SESSION_STARTED,
268 content::NotificationService::AllSources());
270 registrar_->Add(this,
271 chrome::NOTIFICATION_PROFILE_CREATED,
272 content::NotificationService::AllSources());
273 registrar_->Add(this,
274 chrome::NOTIFICATION_PROFILE_DESTROYED,
275 content::NotificationService::AllSources());
278 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
279 content::NotificationService::AllSources());
282 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
283 content::NotificationService::AllSources());
286 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
287 content::NotificationService::AllSources());
290 virtual void Initialize() OVERRIDE {
291 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
293 input_method::InputMethodManager::Get()->AddObserver(this);
296 if (SystemKeyEventListener::GetInstance())
297 SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this);
299 device::BluetoothAdapterFactory::GetAdapter(
300 base::Bind(&SystemTrayDelegate::InitializeOnAdapterReady,
301 ui_weak_ptr_factory_->GetWeakPtr()));
303 ash::Shell::GetInstance()->session_state_delegate()->
304 AddSessionStateObserver(this);
306 if (LoginState::IsInitialized())
307 LoginState::Get()->AddObserver(this);
310 virtual void Shutdown() OVERRIDE {
313 void InitializeOnAdapterReady(
314 scoped_refptr<device::BluetoothAdapter> adapter) {
315 bluetooth_adapter_ = adapter;
316 CHECK(bluetooth_adapter_.get());
317 bluetooth_adapter_->AddObserver(this);
319 local_state_registrar_.reset(new PrefChangeRegistrar);
320 local_state_registrar_->Init(g_browser_process->local_state());
322 UpdateSessionStartTime();
323 UpdateSessionLengthLimit();
325 local_state_registrar_->Add(
326 prefs::kSessionStartTime,
327 base::Bind(&SystemTrayDelegate::UpdateSessionStartTime,
328 base::Unretained(this)));
329 local_state_registrar_->Add(
330 prefs::kSessionLengthLimit,
331 base::Bind(&SystemTrayDelegate::UpdateSessionLengthLimit,
332 base::Unretained(this)));
334 policy::BrowserPolicyConnector* policy_connector =
335 g_browser_process->browser_policy_connector();
336 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
337 policy_connector->GetDeviceCloudPolicyManager();
339 policy_manager->core()->store()->AddObserver(this);
340 UpdateEnterpriseDomain();
343 virtual ~SystemTrayDelegate() {
344 // Unregister PrefChangeRegistrars.
345 local_state_registrar_.reset();
346 user_pref_registrar_.reset();
348 // Unregister content notifications befure destroying any components.
351 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
352 input_method::InputMethodManager::Get()->RemoveObserver(this);
353 if (SystemKeyEventListener::GetInstance())
354 SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this);
355 bluetooth_adapter_->RemoveObserver(this);
356 ash::Shell::GetInstance()->session_state_delegate()->
357 RemoveSessionStateObserver(this);
358 LoginState::Get()->RemoveObserver(this);
360 // Stop observing Drive operations.
361 UnobserveDriveUpdates();
363 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
364 g_browser_process->browser_policy_connector()->
365 GetDeviceCloudPolicyManager();
367 policy_manager->core()->store()->RemoveObserver(this);
370 // Overridden from ash::SystemTrayDelegate:
371 virtual bool GetTrayVisibilityOnStartup() OVERRIDE {
372 // In case of OOBE / sign in screen tray will be shown later.
373 return LoginState::Get()->IsUserLoggedIn();
376 virtual ash::user::LoginStatus GetUserLoginStatus() const OVERRIDE {
377 // All non-logged in ChromeOS specific LOGGED_IN states map to the same
378 // Ash specific LOGGED_IN state.
379 if (!LoginState::Get()->IsUserLoggedIn())
380 return ash::user::LOGGED_IN_NONE;
383 return ash::user::LOGGED_IN_LOCKED;
385 LoginState::LoggedInUserType user_type =
386 LoginState::Get()->GetLoggedInUserType();
388 case LoginState::LOGGED_IN_USER_NONE:
389 return ash::user::LOGGED_IN_NONE;
390 case LoginState::LOGGED_IN_USER_REGULAR:
391 return ash::user::LOGGED_IN_USER;
392 case LoginState::LOGGED_IN_USER_OWNER:
393 return ash::user::LOGGED_IN_OWNER;
394 case LoginState::LOGGED_IN_USER_GUEST:
395 return ash::user::LOGGED_IN_GUEST;
396 case LoginState::LOGGED_IN_USER_RETAIL_MODE:
397 return ash::user::LOGGED_IN_RETAIL_MODE;
398 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
399 return ash::user::LOGGED_IN_PUBLIC;
400 case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED:
401 return ash::user::LOGGED_IN_LOCALLY_MANAGED;
402 case LoginState::LOGGED_IN_USER_KIOSK_APP:
403 return ash::user::LOGGED_IN_KIOSK_APP;
406 return ash::user::LOGGED_IN_NONE;
409 virtual bool IsOobeCompleted() const OVERRIDE {
410 if (!base::SysInfo::IsRunningOnChromeOS() &&
411 LoginState::Get()->IsUserLoggedIn())
413 return StartupUtils::IsOobeCompleted();
416 virtual void ChangeProfilePicture() OVERRIDE {
417 content::RecordAction(
418 content::UserMetricsAction("OpenChangeProfilePictureDialog"));
419 ShowSettingsSubPageForAppropriateBrowser(
420 chrome::kChangeProfilePictureSubPage);
423 virtual const std::string GetEnterpriseDomain() const OVERRIDE {
424 return enterprise_domain_;
427 virtual const string16 GetEnterpriseMessage() const OVERRIDE {
428 if (GetEnterpriseDomain().empty())
430 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE,
431 UTF8ToUTF16(GetEnterpriseDomain()));
434 virtual const std::string GetLocallyManagedUserManager() const OVERRIDE {
435 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
436 return std::string();
437 return UserManager::Get()->GetSupervisedUserManager()->
438 GetManagerDisplayEmail(
439 chromeos::UserManager::Get()->GetActiveUser()->email());
442 virtual const string16 GetLocallyManagedUserManagerName() const OVERRIDE {
443 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
445 return UserManager::Get()->GetSupervisedUserManager()->
446 GetManagerDisplayName(
447 chromeos::UserManager::Get()->GetActiveUser()->email());
450 virtual const string16 GetLocallyManagedUserMessage() const OVERRIDE {
451 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
453 return l10n_util::GetStringFUTF16(
454 IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE,
455 UTF8ToUTF16(GetLocallyManagedUserManager()));
458 virtual bool SystemShouldUpgrade() const OVERRIDE {
459 return UpgradeDetector::GetInstance()->notify_upgrade();
462 virtual base::HourClockType GetHourClockType() const OVERRIDE {
466 virtual void ShowSettings() OVERRIDE {
467 chrome::ScopedTabbedBrowserDisplayer displayer(
468 ProfileManager::GetDefaultProfileOrOffTheRecord(),
469 chrome::HOST_DESKTOP_TYPE_ASH);
470 chrome::ShowSettings(displayer.browser());
473 virtual bool ShouldShowSettings() OVERRIDE {
474 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings();
477 virtual void ShowDateSettings() OVERRIDE {
478 content::RecordAction(content::UserMetricsAction("ShowDateOptions"));
479 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
480 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
481 ShowSettingsSubPageForAppropriateBrowser(sub_page);
484 virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE {
485 if (!LoginState::Get()->IsUserLoggedIn())
487 ShowNetworkSettingsPage(service_path);
490 virtual void ShowBluetoothSettings() OVERRIDE {
491 // TODO(sad): Make this work.
494 virtual void ShowDisplaySettings() OVERRIDE {
495 content::RecordAction(content::UserMetricsAction("ShowDisplayOptions"));
496 ShowSettingsSubPageForAppropriateBrowser(kDisplaySettingsSubPageName);
499 virtual void ShowChromeSlow() OVERRIDE {
500 chrome::ScopedTabbedBrowserDisplayer displayer(
501 ProfileManager::GetDefaultProfileOrOffTheRecord(),
502 chrome::HOST_DESKTOP_TYPE_ASH);
503 chrome::ShowSlow(displayer.browser());
506 virtual bool ShouldShowDisplayNotification() OVERRIDE {
507 // Packaged app is not counted as 'last active', so if a browser opening the
508 // display settings is in background of a packaged app, it will return true.
509 // TODO(mukai): fix this.
510 Browser* active_browser = chrome::FindLastActiveWithHostDesktopType(
511 chrome::HOST_DESKTOP_TYPE_ASH);
515 content::WebContents* active_contents =
516 active_browser->tab_strip_model()->GetActiveWebContents();
517 if (!active_contents)
520 GURL visible_url = active_contents->GetLastCommittedURL();
521 std::string display_settings_url =
522 std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName;
523 std::string display_overscan_url =
524 std::string(chrome::kChromeUISettingsURL) +
525 kDisplayOverscanSettingsSubPageName;
526 return (visible_url.spec() != display_settings_url) &&
527 (visible_url.spec() != display_overscan_url);
530 virtual void ShowDriveSettings() OVERRIDE {
531 // TODO(hshi): Open the drive-specific settings page once we put it in.
532 // For now just show search result for downoads settings.
533 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
534 l10n_util::GetStringUTF8(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME);
535 ShowSettingsSubPageForAppropriateBrowser(sub_page);
538 virtual void ShowIMESettings() OVERRIDE {
539 content::RecordAction(
540 content::UserMetricsAction("OpenLanguageOptionsDialog"));
541 ShowSettingsSubPageForAppropriateBrowser(chrome::kLanguageOptionsSubPage);
544 virtual void ShowHelp() OVERRIDE {
545 chrome::ShowHelpForProfile(
546 ProfileManager::GetDefaultProfileOrOffTheRecord(),
547 chrome::HOST_DESKTOP_TYPE_ASH,
548 chrome::HELP_SOURCE_MENU);
551 virtual void ShowAccessibilityHelp() OVERRIDE {
552 chrome::ScopedTabbedBrowserDisplayer displayer(
553 ProfileManager::GetDefaultProfileOrOffTheRecord(),
554 chrome::HOST_DESKTOP_TYPE_ASH);
555 accessibility::ShowAccessibilityHelp(displayer.browser());
558 virtual void ShowAccessibilitySettings() OVERRIDE {
559 content::RecordAction(
560 content::UserMetricsAction("ShowAccessibilitySettings"));
561 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
562 l10n_util::GetStringUTF8(
563 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY);
564 ShowSettingsSubPageForAppropriateBrowser(sub_page);
567 virtual void ShowPublicAccountInfo() OVERRIDE {
568 chrome::ScopedTabbedBrowserDisplayer displayer(
569 ProfileManager::GetDefaultProfileOrOffTheRecord(),
570 chrome::HOST_DESKTOP_TYPE_ASH);
571 chrome::ShowPolicy(displayer.browser());
574 virtual void ShowLocallyManagedUserInfo() OVERRIDE {
575 // TODO(antrim): find out what should we show in this case.
576 // http://crbug.com/229762
579 virtual void ShowEnterpriseInfo() OVERRIDE {
580 ash::user::LoginStatus status = GetUserLoginStatus();
581 if (status == ash::user::LOGGED_IN_NONE ||
582 status == ash::user::LOGGED_IN_LOCKED) {
583 scoped_refptr<chromeos::HelpAppLauncher> help_app(
584 new chromeos::HelpAppLauncher(GetNativeWindow()));
585 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE);
587 GURL url(google_util::StringAppendGoogleLocaleParam(
588 chrome::kLearnMoreEnterpriseURL));
589 chrome::ScopedTabbedBrowserDisplayer displayer(
590 ProfileManager::GetDefaultProfileOrOffTheRecord(),
591 chrome::HOST_DESKTOP_TYPE_ASH);
592 chrome::ShowSingletonTab(displayer.browser(), url);
596 virtual void ShowUserLogin() OVERRIDE {
597 if (!ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled())
600 // Only regular users could add other users to current session.
601 if (UserManager::Get()->GetActiveUser()->GetType() !=
602 User::USER_TYPE_REGULAR) {
606 // TODO(nkostylev): Show some UI messages why no more users could be added
607 // to this session. http://crbug.com/230863
608 // We limit list of logged in users to 3 due to memory constraints.
609 // TODO(nkostylev): Adjust this limitation based on device capabilites.
610 // http://crbug.com/230865
611 if (UserManager::Get()->GetLoggedInUsers().size() >= 3)
614 // Launch sign in screen to add another user to current session.
615 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size())
616 UserAddingScreen::Get()->Start();
619 virtual void ShutDown() OVERRIDE {
620 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
623 virtual void SignOut() OVERRIDE {
624 chrome::AttemptUserExit();
627 virtual void RequestLockScreen() OVERRIDE {
628 // TODO(antrim) : additional logging for crbug/173178
629 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate";
630 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
633 virtual void RequestRestartForUpdate() OVERRIDE {
634 // We expect that UpdateEngine is in "Reboot for update" state now.
635 chrome::NotifyAndTerminate(true /* fast path */);
638 virtual void GetAvailableBluetoothDevices(
639 ash::BluetoothDeviceList* list) OVERRIDE {
640 device::BluetoothAdapter::DeviceList devices =
641 bluetooth_adapter_->GetDevices();
642 for (size_t i = 0; i < devices.size(); ++i) {
643 device::BluetoothDevice* device = devices[i];
644 ash::BluetoothDeviceInfo info;
645 info.address = device->GetAddress();
646 info.display_name = device->GetName();
647 info.connected = device->IsConnected();
648 info.connecting = device->IsConnecting();
649 info.paired = device->IsPaired();
650 list->push_back(info);
654 virtual void BluetoothStartDiscovering() OVERRIDE {
655 bluetooth_adapter_->StartDiscovering(
656 base::Bind(&base::DoNothing),
657 base::Bind(&BluetoothSetDiscoveringError));
660 virtual void BluetoothStopDiscovering() OVERRIDE {
661 bluetooth_adapter_->StopDiscovering(
662 base::Bind(&base::DoNothing),
663 base::Bind(&BluetoothSetDiscoveringError));
666 virtual void ConnectToBluetoothDevice(const std::string& address) OVERRIDE {
667 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
668 if (!device || device->IsConnecting() ||
669 (device->IsConnected() && device->IsPaired())) {
672 if (device->IsPaired() && !device->IsConnectable())
674 if (device->IsPaired() || !device->IsPairable()) {
677 base::Bind(&base::DoNothing),
678 base::Bind(&BluetoothDeviceConnectError));
679 } else { // Show paring dialog for the unpaired device.
680 BluetoothPairingDialog* dialog =
681 new BluetoothPairingDialog(GetNativeWindow(), device);
682 // The dialog deletes itself on close.
687 virtual bool IsBluetoothDiscovering() OVERRIDE {
688 return bluetooth_adapter_->IsDiscovering();
691 virtual void GetCurrentIME(ash::IMEInfo* info) OVERRIDE {
692 input_method::InputMethodManager* manager =
693 input_method::InputMethodManager::Get();
694 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
695 input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod();
696 ExtractIMEInfo(ime, *util, info);
697 info->selected = true;
700 virtual void GetAvailableIMEList(ash::IMEInfoList* list) OVERRIDE {
701 input_method::InputMethodManager* manager =
702 input_method::InputMethodManager::Get();
703 input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
704 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors(
705 manager->GetActiveInputMethods());
706 std::string current = manager->GetCurrentInputMethod().id();
707 for (size_t i = 0; i < ime_descriptors->size(); i++) {
708 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i);
710 ExtractIMEInfo(ime, *util, &info);
711 info.selected = ime.id() == current;
712 list->push_back(info);
716 virtual void GetCurrentIMEProperties(
717 ash::IMEPropertyInfoList* list) OVERRIDE {
718 input_method::InputMethodManager* manager =
719 input_method::InputMethodManager::Get();
720 input_method::InputMethodPropertyList properties =
721 manager->GetCurrentInputMethodProperties();
722 for (size_t i = 0; i < properties.size(); ++i) {
723 ash::IMEPropertyInfo property;
724 property.key = properties[i].key;
725 property.name = base::UTF8ToUTF16(properties[i].label);
726 property.selected = properties[i].is_selection_item_checked;
727 list->push_back(property);
731 virtual void SwitchIME(const std::string& ime_id) OVERRIDE {
732 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id);
735 virtual void ActivateIMEProperty(const std::string& key) OVERRIDE {
736 input_method::InputMethodManager::Get()->
737 ActivateInputMethodProperty(key);
740 virtual void CancelDriveOperation(int32 operation_id) OVERRIDE {
741 DriveIntegrationService* integration_service =
742 FindDriveIntegrationService();
743 if (!integration_service)
746 integration_service->job_list()->CancelJob(operation_id);
749 virtual void GetDriveOperationStatusList(
750 ash::DriveOperationStatusList* list) OVERRIDE {
751 DriveIntegrationService* integration_service =
752 FindDriveIntegrationService();
753 if (!integration_service)
756 *list = ConvertToDriveStatusList(
757 integration_service->job_list()->GetJobInfoList());
760 virtual void ShowNetworkConfigure(const std::string& network_id,
761 gfx::NativeWindow parent_window) OVERRIDE {
762 NetworkConfigView::Show(network_id, parent_window);
765 virtual bool EnrollNetwork(const std::string& network_id,
766 gfx::NativeWindow parent_window) OVERRIDE {
767 return enrollment::CreateDialog(network_id, parent_window);
770 virtual void ManageBluetoothDevices() OVERRIDE {
771 content::RecordAction(
772 content::UserMetricsAction("ShowBluetoothSettingsPage"));
773 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
774 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH);
775 ShowSettingsSubPageForAppropriateBrowser(sub_page);
778 virtual void ToggleBluetooth() OVERRIDE {
779 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(),
780 base::Bind(&base::DoNothing),
781 base::Bind(&BluetoothPowerFailure));
784 virtual void ShowMobileSimDialog() OVERRIDE {
785 SimDialogDelegate::ShowDialog(GetNativeWindow(),
786 SimDialogDelegate::SIM_DIALOG_UNLOCK);
789 virtual void ShowMobileSetupDialog(const std::string& service_path) OVERRIDE {
790 MobileSetupDialog::Show(service_path);
793 virtual void ShowOtherNetworkDialog(const std::string& type) OVERRIDE {
794 if (type == shill::kTypeCellular) {
795 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
798 NetworkConfigView::ShowForType(type, GetNativeWindow());
801 virtual bool GetBluetoothAvailable() OVERRIDE {
802 return bluetooth_adapter_->IsPresent();
805 virtual bool GetBluetoothEnabled() OVERRIDE {
806 return bluetooth_adapter_->IsPowered();
809 virtual void ChangeProxySettings() OVERRIDE {
810 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE);
811 LoginDisplayHostImpl::default_host()->OpenProxySettings();
814 virtual ash::VolumeControlDelegate*
815 GetVolumeControlDelegate() const OVERRIDE {
816 return volume_control_delegate_.get();
819 virtual void SetVolumeControlDelegate(
820 scoped_ptr<ash::VolumeControlDelegate> delegate) OVERRIDE {
821 volume_control_delegate_.swap(delegate);
824 virtual bool GetSessionStartTime(
825 base::TimeTicks* session_start_time) OVERRIDE {
826 *session_start_time = session_start_time_;
827 return have_session_start_time_;
830 virtual bool GetSessionLengthLimit(
831 base::TimeDelta* session_length_limit) OVERRIDE {
832 *session_length_limit = session_length_limit_;
833 return have_session_length_limit_;
836 virtual int GetSystemTrayMenuWidth() OVERRIDE {
837 return l10n_util::GetLocalizedContentsWidthInPixels(
838 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS);
841 virtual void MaybeSpeak(const std::string& utterance) const OVERRIDE {
842 AccessibilityManager::Get()->MaybeSpeak(utterance);
846 ash::SystemTray* GetPrimarySystemTray() {
847 return ash::Shell::GetInstance()->GetPrimarySystemTray();
850 ash::SystemTrayNotifier* GetSystemTrayNotifier() {
851 return ash::Shell::GetInstance()->system_tray_notifier();
854 void SetProfile(Profile* profile) {
855 // Stop observing the current |user_profile_| on Drive integration status.
856 UnobserveDriveUpdates();
858 user_profile_ = profile;
860 // Restart observation, now for the newly set |profile|.
861 ObserveDriveUpdates();
863 PrefService* prefs = profile->GetPrefs();
864 user_pref_registrar_.reset(new PrefChangeRegistrar);
865 user_pref_registrar_->Init(prefs);
866 user_pref_registrar_->Add(
867 prefs::kUse24HourClock,
868 base::Bind(&SystemTrayDelegate::UpdateClockType,
869 base::Unretained(this)));
870 user_pref_registrar_->Add(
871 prefs::kLanguageRemapSearchKeyTo,
872 base::Bind(&SystemTrayDelegate::OnLanguageRemapSearchKeyToChanged,
873 base::Unretained(this)));
874 user_pref_registrar_->Add(
875 prefs::kShowLogoutButtonInTray,
876 base::Bind(&SystemTrayDelegate::UpdateShowLogoutButtonInTray,
877 base::Unretained(this)));
878 user_pref_registrar_->Add(
879 prefs::kLargeCursorEnabled,
880 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged,
881 base::Unretained(this),
882 ash::A11Y_NOTIFICATION_NONE));
883 user_pref_registrar_->Add(
884 prefs::kAutoclickEnabled,
885 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged,
886 base::Unretained(this),
887 ash::A11Y_NOTIFICATION_NONE));
888 user_pref_registrar_->Add(
889 prefs::kShouldAlwaysShowAccessibilityMenu,
890 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged,
891 base::Unretained(this),
892 ash::A11Y_NOTIFICATION_NONE));
893 user_pref_registrar_->Add(
894 prefs::kPerformanceTracingEnabled,
895 base::Bind(&SystemTrayDelegate::UpdatePerformanceTracing,
896 base::Unretained(this)));
899 UpdateShowLogoutButtonInTray();
900 UpdatePerformanceTracing();
901 search_key_mapped_to_ =
902 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo);
905 bool UnsetProfile(Profile* profile) {
906 if (profile != user_profile_)
908 user_pref_registrar_.reset();
912 void ObserveDriveUpdates() {
913 DriveIntegrationService* integration_service =
914 FindDriveIntegrationService();
915 if (integration_service)
916 integration_service->job_list()->AddObserver(this);
919 void UnobserveDriveUpdates() {
920 DriveIntegrationService* integration_service =
921 FindDriveIntegrationService();
922 if (integration_service)
923 integration_service->job_list()->RemoveObserver(this);
926 bool ShouldUse24HourClock() const {
927 // On login screen and in guest mode owner default is used for
928 // kUse24HourClock preference.
929 const ash::user::LoginStatus status = GetUserLoginStatus();
930 const CrosSettings* const cros_settings = CrosSettings::Get();
931 bool system_use_24_hour_clock = true;
932 const bool system_value_found = cros_settings->GetBoolean(
933 kSystemUse24HourClock, &system_use_24_hour_clock);
935 if (status == ash::user::LOGGED_IN_NONE)
936 return (system_value_found
937 ? system_use_24_hour_clock
938 : (base::GetHourClockType() == base::k24HourClock));
940 const PrefService::Preference* user_pref =
941 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock);
942 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue())
943 return (system_value_found
944 ? system_use_24_hour_clock
945 : (base::GetHourClockType() == base::k24HourClock));
947 bool use_24_hour_clock = true;
948 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock);
949 return use_24_hour_clock;
952 void UpdateClockType() {
953 if (!user_pref_registrar_)
956 const bool use_24_hour_clock = ShouldUse24HourClock();
957 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock;
958 GetSystemTrayNotifier()->NotifyDateFormatChanged();
959 // This also works for enterprise-managed devices because they never have
961 if (chromeos::UserManager::Get()->IsCurrentUserOwner())
962 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
965 void UpdateShowLogoutButtonInTray() {
966 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
967 user_pref_registrar_->prefs()->GetBoolean(
968 prefs::kShowLogoutButtonInTray));
971 void UpdateSessionStartTime() {
972 const PrefService* local_state = local_state_registrar_->prefs();
973 if (local_state->HasPrefPath(prefs::kSessionStartTime)) {
974 have_session_start_time_ = true;
975 session_start_time_ = base::TimeTicks::FromInternalValue(
976 local_state->GetInt64(prefs::kSessionStartTime));
978 have_session_start_time_ = false;
979 session_start_time_ = base::TimeTicks();
981 GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
984 void UpdateSessionLengthLimit() {
985 const PrefService* local_state = local_state_registrar_->prefs();
986 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) {
987 have_session_length_limit_ = true;
988 session_length_limit_ = base::TimeDelta::FromMilliseconds(
989 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit),
990 kSessionLengthLimitMinMs),
991 kSessionLengthLimitMaxMs));
993 have_session_length_limit_ = false;
994 session_length_limit_ = base::TimeDelta();
996 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
999 // LoginState::Observer overrides.
1000 virtual void LoggedInStateChanged() OVERRIDE {
1004 // Overridden from SessionManagerClient::Observer.
1005 virtual void LockScreen() OVERRIDE {
1006 screen_locked_ = true;
1007 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1008 GetUserLoginStatus());
1011 virtual void ScreenIsUnlocked() OVERRIDE {
1012 screen_locked_ = false;
1013 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1014 GetUserLoginStatus());
1017 gfx::NativeWindow GetNativeWindow() const {
1018 bool session_started = ash::Shell::GetInstance()->session_state_delegate()
1019 ->IsActiveUserSessionStarted();
1020 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started);
1023 // content::NotificationObserver implementation.
1024 virtual void Observe(int type,
1025 const content::NotificationSource& source,
1026 const content::NotificationDetails& details) OVERRIDE {
1028 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
1029 UpgradeDetector* detector =
1030 content::Source<UpgradeDetector>(source).ptr();
1031 ash::UpdateObserver::UpdateSeverity severity =
1032 ash::UpdateObserver::UPDATE_NORMAL;
1033 switch (detector->upgrade_notification_stage()) {
1034 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
1035 severity = ash::UpdateObserver::UPDATE_SEVERE_RED;
1038 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
1039 severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE;
1042 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
1043 severity = ash::UpdateObserver::UPDATE_LOW_GREEN;
1046 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
1048 severity = ash::UpdateObserver::UPDATE_NORMAL;
1051 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity);
1054 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
1055 // This notification is also sent on login screen when user avatar
1056 // is loaded from file.
1057 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) {
1058 GetSystemTrayNotifier()->NotifyUserUpdate();
1062 case chrome::NOTIFICATION_PROFILE_CREATED: {
1063 SetProfile(content::Source<Profile>(source).ptr());
1064 registrar_->Remove(this,
1065 chrome::NOTIFICATION_PROFILE_CREATED,
1066 content::NotificationService::AllSources());
1069 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1070 if (UnsetProfile(content::Source<Profile>(source).ptr())) {
1071 registrar_->Remove(this,
1072 chrome::NOTIFICATION_PROFILE_DESTROYED,
1073 content::NotificationService::AllSources());
1077 case chrome::NOTIFICATION_SESSION_STARTED: {
1078 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
1079 GetUserLoginStatus());
1080 SetProfile(ProfileManager::GetDefaultProfile());
1083 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK:
1084 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE:
1085 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: {
1086 AccessibilityStatusEventDetails* accessibility_status =
1087 content::Details<AccessibilityStatusEventDetails>(details).ptr();
1088 OnAccessibilityModeChanged(accessibility_status->notify);
1096 void OnLanguageRemapSearchKeyToChanged() {
1097 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger(
1098 prefs::kLanguageRemapSearchKeyTo);
1101 void OnAccessibilityModeChanged(
1102 ash::AccessibilityNotificationVisibility notify) {
1103 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify);
1106 void UpdatePerformanceTracing() {
1107 if (!user_pref_registrar_)
1110 user_pref_registrar_->prefs()->GetBoolean(
1111 prefs::kPerformanceTracingEnabled);
1112 GetSystemTrayNotifier()->NotifyTracingModeChanged(value);
1115 // Overridden from InputMethodManager::Observer.
1116 virtual void InputMethodChanged(
1117 input_method::InputMethodManager* manager, bool show_message) OVERRIDE {
1118 GetSystemTrayNotifier()->NotifyRefreshIME(show_message);
1121 virtual void InputMethodPropertyChanged(
1122 input_method::InputMethodManager* manager) OVERRIDE {
1123 GetSystemTrayNotifier()->NotifyRefreshIME(false);
1126 // drive::JobListObserver overrides.
1127 virtual void OnJobAdded(const drive::JobInfo& job_info) OVERRIDE {
1128 OnJobUpdated(job_info);
1131 virtual void OnJobDone(const drive::JobInfo& job_info,
1132 drive::FileError error) OVERRIDE {
1133 ash::DriveOperationStatus status;
1134 if (ConvertToFinishedDriveOperationStatus(job_info, error, &status))
1135 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status);
1138 virtual void OnJobUpdated(const drive::JobInfo& job_info) OVERRIDE {
1139 ash::DriveOperationStatus status;
1140 if (ConvertToDriveOperationStatus(job_info, &status))
1141 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status);
1144 DriveIntegrationService* FindDriveIntegrationService() {
1145 return user_profile_ ?
1146 DriveIntegrationServiceFactory::FindForProfile(user_profile_) : NULL;
1149 // Overridden from BluetoothAdapter::Observer.
1150 virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
1151 bool present) OVERRIDE {
1152 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1155 virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
1156 bool powered) OVERRIDE {
1157 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1160 virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter,
1161 bool discovering) OVERRIDE {
1162 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
1165 virtual void DeviceAdded(device::BluetoothAdapter* adapter,
1166 device::BluetoothDevice* device) OVERRIDE {
1167 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1170 virtual void DeviceChanged(device::BluetoothAdapter* adapter,
1171 device::BluetoothDevice* device) OVERRIDE {
1172 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1175 virtual void DeviceRemoved(device::BluetoothAdapter* adapter,
1176 device::BluetoothDevice* device) OVERRIDE {
1177 GetSystemTrayNotifier()->NotifyRefreshBluetooth();
1180 // Overridden from SystemKeyEventListener::CapsLockObserver.
1181 virtual void OnCapsLockChange(bool enabled) OVERRIDE {
1182 bool search_mapped_to_caps_lock = false;
1183 if (!base::SysInfo::IsRunningOnChromeOS() ||
1184 search_key_mapped_to_ == input_method::kCapsLockKey)
1185 search_mapped_to_caps_lock = true;
1186 GetSystemTrayNotifier()->NotifyCapsLockChanged(
1187 enabled, search_mapped_to_caps_lock);
1190 void UpdateEnterpriseDomain() {
1191 std::string enterprise_domain =
1192 g_browser_process->browser_policy_connector()->GetEnterpriseDomain();
1193 if (enterprise_domain_ != enterprise_domain) {
1194 enterprise_domain_ = enterprise_domain;
1195 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
1199 // Overridden from CloudPolicyStore::Observer
1200 virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE {
1201 UpdateEnterpriseDomain();
1204 virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE {
1205 UpdateEnterpriseDomain();
1208 // Overridden from ash::SessionStateObserver
1209 virtual void ActiveUserChanged(const std::string& user_id) OVERRIDE {
1210 GetSystemTrayNotifier()->NotifyUserUpdate();
1213 virtual void UserAddedToSession(const std::string& user_id) OVERRIDE {
1214 GetSystemTrayNotifier()->NotifyUserAddedToSession();
1217 scoped_ptr<base::WeakPtrFactory<SystemTrayDelegate> > ui_weak_ptr_factory_;
1218 scoped_ptr<content::NotificationRegistrar> registrar_;
1219 scoped_ptr<PrefChangeRegistrar> local_state_registrar_;
1220 scoped_ptr<PrefChangeRegistrar> user_pref_registrar_;
1221 Profile* user_profile_;
1222 base::HourClockType clock_type_;
1223 int search_key_mapped_to_;
1224 bool screen_locked_;
1225 bool have_session_start_time_;
1226 base::TimeTicks session_start_time_;
1227 bool have_session_length_limit_;
1228 base::TimeDelta session_length_limit_;
1229 std::string enterprise_domain_;
1231 scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
1232 scoped_ptr<ash::VolumeControlDelegate> volume_control_delegate_;
1234 DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegate);
1239 ash::SystemTrayDelegate* CreateSystemTrayDelegate() {
1240 return new chromeos::SystemTrayDelegate();
1243 } // namespace chromeos