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