system_tray_delegate_chromeos.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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. 4 5#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h" 6 7#include <algorithm> 8#include <set> 9#include <string> 10#include <vector> 11 12#include "ash/ash_switches.h" 13#include "ash/desktop_background/desktop_background_controller.h" 14#include "ash/ime/input_method_menu_item.h" 15#include "ash/ime/input_method_menu_manager.h" 16#include "ash/metrics/user_metrics_recorder.h" 17#include "ash/session/session_state_delegate.h" 18#include "ash/session/session_state_observer.h" 19#include "ash/shell.h" 20#include "ash/shell_delegate.h" 21#include "ash/shell_window_ids.h" 22#include "ash/system/bluetooth/bluetooth_observer.h" 23#include "ash/system/chromeos/session/logout_button_observer.h" 24#include "ash/system/date/clock_observer.h" 25#include "ash/system/ime/ime_observer.h" 26#include "ash/system/tray/system_tray.h" 27#include "ash/system/tray/system_tray_delegate.h" 28#include "ash/system/tray/system_tray_notifier.h" 29#include "ash/system/tray_accessibility.h" 30#include "ash/system/user/login_status.h" 31#include "ash/system/user/update_observer.h" 32#include "ash/system/user/user_observer.h" 33#include "ash/volume_control_delegate.h" 34#include "ash/wm/lock_state_controller.h" 35#include "base/bind_helpers.h" 36#include "base/callback.h" 37#include "base/logging.h" 38#include "base/memory/weak_ptr.h" 39#include "base/prefs/pref_service.h" 40#include "base/strings/stringprintf.h" 41#include "base/strings/utf_string_conversions.h" 42#include "base/sys_info.h" 43#include "base/time/time.h" 44#include "chrome/browser/browser_process.h" 45#include "chrome/browser/chrome_notification_types.h" 46#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 47#include "chrome/browser/chromeos/accessibility/magnification_manager.h" 48#include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h" 49#include "chrome/browser/chromeos/charger_replace/charger_replacement_dialog.h" 50#include "chrome/browser/chromeos/enrollment_dialog_view.h" 51#include "chrome/browser/chromeos/events/system_key_event_listener.h" 52#include "chrome/browser/chromeos/input_method/input_method_util.h" 53#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" 54#include "chrome/browser/chromeos/login/help_app_launcher.h" 55#include "chrome/browser/chromeos/login/login_wizard.h" 56#include "chrome/browser/chromeos/login/ui/login_display_host.h" 57#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 58#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" 59#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 60#include "chrome/browser/chromeos/login/users/user_manager.h" 61#include "chrome/browser/chromeos/options/network_config_view.h" 62#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 63#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 64#include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h" 65#include "chrome/browser/chromeos/profiles/profile_helper.h" 66#include "chrome/browser/chromeos/set_time_dialog.h" 67#include "chrome/browser/chromeos/settings/cros_settings.h" 68#include "chrome/browser/chromeos/sim_dialog_delegate.h" 69#include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h" 70#include "chrome/browser/lifetime/application_lifetime.h" 71#include "chrome/browser/profiles/profile_manager.h" 72#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 73#include "chrome/browser/ui/ash/user_accounts_delegate_chromeos.h" 74#include "chrome/browser/ui/ash/volume_controller_chromeos.h" 75#include "chrome/browser/ui/browser.h" 76#include "chrome/browser/ui/browser_finder.h" 77#include "chrome/browser/ui/browser_list.h" 78#include "chrome/browser/ui/chrome_pages.h" 79#include "chrome/browser/ui/host_desktop.h" 80#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 81#include "chrome/browser/ui/singleton_tabs.h" 82#include "chrome/browser/ui/tabs/tab_strip_model.h" 83#include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h" 84#include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" 85#include "chrome/browser/upgrade_detector.h" 86#include "chrome/common/chrome_switches.h" 87#include "chrome/common/pref_names.h" 88#include "chrome/common/url_constants.h" 89#include "chromeos/dbus/dbus_thread_manager.h" 90#include "chromeos/dbus/session_manager_client.h" 91#include "chromeos/ime/extension_ime_util.h" 92#include "chromeos/ime/ime_keyboard.h" 93#include "chromeos/ime/input_method_manager.h" 94#include "chromeos/login/login_state.h" 95#include "chromeos/network/portal_detector/network_portal_detector.h" 96#include "components/google/core/browser/google_util.h" 97#include "components/policy/core/common/cloud/cloud_policy_store.h" 98#include "components/user_manager/user.h" 99#include "components/user_manager/user_type.h" 100#include "content/public/browser/notification_observer.h" 101#include "content/public/browser/notification_service.h" 102#include "content/public/browser/user_metrics.h" 103#include "content/public/browser/web_contents.h" 104#include "device/bluetooth/bluetooth_adapter.h" 105#include "device/bluetooth/bluetooth_adapter_factory.h" 106#include "device/bluetooth/bluetooth_device.h" 107#include "grit/ash_strings.h" 108#include "grit/generated_resources.h" 109#include "grit/locale_settings.h" 110#include "net/base/escape.h" 111#include "third_party/cros_system_api/dbus/service_constants.h" 112#include "ui/base/l10n/l10n_util.h" 113#include "ui/base/l10n/time_format.h" 114 115namespace chromeos { 116 117namespace { 118 119// The minimum session length limit that can be set. 120const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds. 121 122// The maximum session length limit that can be set. 123const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours. 124 125const char kDisplaySettingsSubPageName[] = "display"; 126const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan"; 127 128void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, 129 const input_method::InputMethodUtil& util, 130 ash::IMEInfo* info) { 131 info->id = ime.id(); 132 info->name = util.GetInputMethodLongName(ime); 133 info->medium_name = util.GetInputMethodMediumName(ime); 134 info->short_name = util.GetInputMethodShortName(ime); 135 info->third_party = extension_ime_util::IsExtensionIME(ime.id()); 136} 137 138gfx::NativeWindow GetNativeWindowByStatus(ash::user::LoginStatus login_status, 139 bool session_started) { 140 int container_id = 141 (!session_started || login_status == ash::user::LOGGED_IN_NONE || 142 login_status == ash::user::LOGGED_IN_LOCKED) 143 ? ash::kShellWindowId_LockSystemModalContainer 144 : ash::kShellWindowId_SystemModalContainer; 145 return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), 146 container_id); 147} 148 149void BluetoothPowerFailure() { 150 // TODO(sad): Show an error bubble? 151} 152 153void BluetoothSetDiscoveringError() { 154 LOG(ERROR) << "BluetoothSetDiscovering failed."; 155} 156 157void BluetoothDeviceConnectError( 158 device::BluetoothDevice::ConnectErrorCode error_code) { 159 // TODO(sad): Do something? 160} 161 162void ShowSettingsSubPageForActiveUser(const std::string& sub_page) { 163 chrome::ShowSettingsSubPageForProfile( 164 ProfileManager::GetActiveUserProfile(), sub_page); 165} 166 167void ShowNetworkSettingsPage(const std::string& service_path) { 168 std::string page = chrome::kInternetOptionsSubPage; 169 page += "?servicePath=" + net::EscapeUrlEncodedData(service_path, true); 170 content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog")); 171 ShowSettingsSubPageForActiveUser(page); 172} 173 174void OnAcceptMultiprofilesIntro(bool no_show_again) { 175 PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); 176 prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again); 177 UserAddingScreen::Get()->Start(); 178} 179 180} // namespace 181 182SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS() 183 : weak_ptr_factory_(this), 184 user_profile_(NULL), 185 clock_type_(base::GetHourClockType()), 186 search_key_mapped_to_(input_method::kSearchKey), 187 screen_locked_(false), 188 have_session_start_time_(false), 189 have_session_length_limit_(false), 190 should_run_bluetooth_discovery_(false), 191 volume_control_delegate_(new VolumeController()), 192 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver( 193 kSystemUse24HourClock, 194 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType, 195 base::Unretained(this)))) { 196 // Register notifications on construction so that events such as 197 // PROFILE_CREATED do not get missed if they happen before Initialize(). 198 registrar_.reset(new content::NotificationRegistrar); 199 registrar_->Add(this, 200 chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 201 content::NotificationService::AllSources()); 202 registrar_->Add(this, 203 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, 204 content::NotificationService::AllSources()); 205 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) { 206 registrar_->Add(this, 207 chrome::NOTIFICATION_SESSION_STARTED, 208 content::NotificationService::AllSources()); 209 } 210 registrar_->Add(this, 211 chrome::NOTIFICATION_PROFILE_CREATED, 212 content::NotificationService::AllSources()); 213 registrar_->Add(this, 214 chrome::NOTIFICATION_PROFILE_DESTROYED, 215 content::NotificationService::AllSources()); 216 217 AccessibilityManager* accessibility_manager = AccessibilityManager::Get(); 218 CHECK(accessibility_manager); 219 accessibility_subscription_ = accessibility_manager->RegisterCallback( 220 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged, 221 base::Unretained(this))); 222} 223 224void SystemTrayDelegateChromeOS::Initialize() { 225 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); 226 227 input_method::InputMethodManager::Get()->AddObserver(this); 228 ash::ime::InputMethodMenuManager::GetInstance()->AddObserver(this); 229 UpdateClockType(); 230 231 device::BluetoothAdapterFactory::GetAdapter( 232 base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady, 233 weak_ptr_factory_.GetWeakPtr())); 234 235 ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver( 236 this); 237 238 if (LoginState::IsInitialized()) 239 LoginState::Get()->AddObserver(this); 240 241 if (CrasAudioHandler::IsInitialized()) 242 CrasAudioHandler::Get()->AddAudioObserver(this); 243 244 BrowserList::AddObserver(this); 245} 246 247void SystemTrayDelegateChromeOS::Shutdown() { 248 device_settings_observer_.reset(); 249} 250 251void SystemTrayDelegateChromeOS::InitializeOnAdapterReady( 252 scoped_refptr<device::BluetoothAdapter> adapter) { 253 bluetooth_adapter_ = adapter; 254 CHECK(bluetooth_adapter_.get()); 255 bluetooth_adapter_->AddObserver(this); 256 257 local_state_registrar_.reset(new PrefChangeRegistrar); 258 local_state_registrar_->Init(g_browser_process->local_state()); 259 260 UpdateSessionStartTime(); 261 UpdateSessionLengthLimit(); 262 263 local_state_registrar_->Add( 264 prefs::kSessionStartTime, 265 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime, 266 base::Unretained(this))); 267 local_state_registrar_->Add( 268 prefs::kSessionLengthLimit, 269 base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit, 270 base::Unretained(this))); 271 272 policy::BrowserPolicyConnectorChromeOS* policy_connector = 273 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 274 policy::DeviceCloudPolicyManagerChromeOS* policy_manager = 275 policy_connector->GetDeviceCloudPolicyManager(); 276 if (policy_manager) 277 policy_manager->core()->store()->AddObserver(this); 278 UpdateEnterpriseDomain(); 279} 280 281SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() { 282 // Unregister PrefChangeRegistrars. 283 local_state_registrar_.reset(); 284 user_pref_registrar_.reset(); 285 286 // Unregister content notifications before destroying any components. 287 registrar_.reset(); 288 289 // Unregister a11y status subscription. 290 accessibility_subscription_.reset(); 291 292 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); 293 input_method::InputMethodManager::Get()->RemoveObserver(this); 294 ash::ime::InputMethodMenuManager::GetInstance()->RemoveObserver(this); 295 bluetooth_adapter_->RemoveObserver(this); 296 ash::Shell::GetInstance() 297 ->session_state_delegate() 298 ->RemoveSessionStateObserver(this); 299 LoginState::Get()->RemoveObserver(this); 300 301 if (CrasAudioHandler::IsInitialized()) 302 CrasAudioHandler::Get()->RemoveAudioObserver(this); 303 304 BrowserList::RemoveObserver(this); 305 StopObservingAppWindowRegistry(); 306 307 policy::BrowserPolicyConnectorChromeOS* connector = 308 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 309 policy::DeviceCloudPolicyManagerChromeOS* policy_manager = 310 connector->GetDeviceCloudPolicyManager(); 311 if (policy_manager) 312 policy_manager->core()->store()->RemoveObserver(this); 313} 314 315// Overridden from ash::SystemTrayDelegate: 316bool SystemTrayDelegateChromeOS::GetTrayVisibilityOnStartup() { 317 // In case of OOBE / sign in screen tray will be shown later. 318 return LoginState::Get()->IsUserLoggedIn(); 319} 320 321ash::user::LoginStatus SystemTrayDelegateChromeOS::GetUserLoginStatus() const { 322 // All non-logged in ChromeOS specific LOGGED_IN states map to the same 323 // Ash specific LOGGED_IN state. 324 if (!LoginState::Get()->IsUserLoggedIn()) 325 return ash::user::LOGGED_IN_NONE; 326 327 if (screen_locked_) 328 return ash::user::LOGGED_IN_LOCKED; 329 330 LoginState::LoggedInUserType user_type = 331 LoginState::Get()->GetLoggedInUserType(); 332 switch (user_type) { 333 case LoginState::LOGGED_IN_USER_NONE: 334 return ash::user::LOGGED_IN_NONE; 335 case LoginState::LOGGED_IN_USER_REGULAR: 336 return ash::user::LOGGED_IN_USER; 337 case LoginState::LOGGED_IN_USER_OWNER: 338 return ash::user::LOGGED_IN_OWNER; 339 case LoginState::LOGGED_IN_USER_GUEST: 340 return ash::user::LOGGED_IN_GUEST; 341 case LoginState::LOGGED_IN_USER_RETAIL_MODE: 342 return ash::user::LOGGED_IN_RETAIL_MODE; 343 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT: 344 return ash::user::LOGGED_IN_PUBLIC; 345 case LoginState::LOGGED_IN_USER_SUPERVISED: 346 return ash::user::LOGGED_IN_SUPERVISED; 347 case LoginState::LOGGED_IN_USER_KIOSK_APP: 348 return ash::user::LOGGED_IN_KIOSK_APP; 349 } 350 NOTREACHED(); 351 return ash::user::LOGGED_IN_NONE; 352} 353 354void SystemTrayDelegateChromeOS::ChangeProfilePicture() { 355 content::RecordAction( 356 base::UserMetricsAction("OpenChangeProfilePictureDialog")); 357 ShowSettingsSubPageForActiveUser(chrome::kChangeProfilePictureSubPage); 358} 359 360const std::string SystemTrayDelegateChromeOS::GetEnterpriseDomain() const { 361 return enterprise_domain_; 362} 363 364const base::string16 SystemTrayDelegateChromeOS::GetEnterpriseMessage() const { 365 if (GetEnterpriseDomain().empty()) 366 return base::string16(); 367 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE, 368 base::UTF8ToUTF16(GetEnterpriseDomain())); 369} 370 371const std::string SystemTrayDelegateChromeOS::GetSupervisedUserManager() const { 372 if (GetUserLoginStatus() != ash::user::LOGGED_IN_SUPERVISED) 373 return std::string(); 374 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayEmail( 375 chromeos::UserManager::Get()->GetActiveUser()->email()); 376} 377 378const base::string16 379SystemTrayDelegateChromeOS::GetSupervisedUserManagerName() const { 380 if (GetUserLoginStatus() != ash::user::LOGGED_IN_SUPERVISED) 381 return base::string16(); 382 return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayName( 383 chromeos::UserManager::Get()->GetActiveUser()->email()); 384} 385 386const base::string16 SystemTrayDelegateChromeOS::GetSupervisedUserMessage() 387 const { 388 if (GetUserLoginStatus() != ash::user::LOGGED_IN_SUPERVISED) 389 return base::string16(); 390 return l10n_util::GetStringFUTF16( 391 IDS_USER_IS_SUPERVISED_BY_NOTICE, 392 base::UTF8ToUTF16(GetSupervisedUserManager())); 393} 394 395bool SystemTrayDelegateChromeOS::SystemShouldUpgrade() const { 396 return UpgradeDetector::GetInstance()->notify_upgrade(); 397} 398 399base::HourClockType SystemTrayDelegateChromeOS::GetHourClockType() const { 400 return clock_type_; 401} 402 403void SystemTrayDelegateChromeOS::ShowSettings() { 404 ShowSettingsSubPageForActiveUser(""); 405} 406 407bool SystemTrayDelegateChromeOS::ShouldShowSettings() { 408 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings(); 409} 410 411void SystemTrayDelegateChromeOS::ShowDateSettings() { 412 content::RecordAction(base::UserMetricsAction("ShowDateOptions")); 413 std::string sub_page = 414 std::string(chrome::kSearchSubPage) + "#" + 415 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME); 416 // Everybody can change the time zone (even though it is a device setting). 417 ShowSettingsSubPageForActiveUser(sub_page); 418} 419 420void SystemTrayDelegateChromeOS::ShowSetTimeDialog() { 421 SetTimeDialog::ShowDialog(GetNativeWindow()); 422} 423 424void SystemTrayDelegateChromeOS::ShowNetworkSettings( 425 const std::string& service_path) { 426 if (!LoginState::Get()->IsUserLoggedIn()) 427 return; 428 ShowNetworkSettingsPage(service_path); 429} 430 431void SystemTrayDelegateChromeOS::ShowBluetoothSettings() { 432 // TODO(sad): Make this work. 433} 434 435void SystemTrayDelegateChromeOS::ShowDisplaySettings() { 436 content::RecordAction(base::UserMetricsAction("ShowDisplayOptions")); 437 ShowSettingsSubPageForActiveUser(kDisplaySettingsSubPageName); 438} 439 440void SystemTrayDelegateChromeOS::ShowChromeSlow() { 441 chrome::ScopedTabbedBrowserDisplayer displayer( 442 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); 443 chrome::ShowSlow(displayer.browser()); 444} 445 446bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() { 447 // Packaged app is not counted as 'last active', so if a browser opening the 448 // display settings is in background of a packaged app, it will return true. 449 // TODO(mukai): fix this. 450 Browser* active_browser = 451 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); 452 if (!active_browser) 453 return true; 454 455 content::WebContents* active_contents = 456 active_browser->tab_strip_model()->GetActiveWebContents(); 457 if (!active_contents) 458 return true; 459 460 GURL visible_url = active_contents->GetLastCommittedURL(); 461 GURL display_settings_url = 462 chrome::GetSettingsUrl(kDisplaySettingsSubPageName); 463 GURL display_overscan_url = 464 chrome::GetSettingsUrl(kDisplayOverscanSettingsSubPageName); 465 return (visible_url != display_settings_url && 466 visible_url != display_overscan_url); 467} 468 469void SystemTrayDelegateChromeOS::ShowIMESettings() { 470 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog")); 471 ShowSettingsSubPageForActiveUser(chrome::kLanguageOptionsSubPage); 472} 473 474void SystemTrayDelegateChromeOS::ShowHelp() { 475 chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(), 476 chrome::HOST_DESKTOP_TYPE_ASH, 477 chrome::HELP_SOURCE_MENU); 478} 479 480void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() { 481 chrome::ScopedTabbedBrowserDisplayer displayer( 482 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); 483 accessibility::ShowAccessibilityHelp(displayer.browser()); 484} 485 486void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() { 487 content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings")); 488 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + 489 l10n_util::GetStringUTF8( 490 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY); 491 ShowSettingsSubPageForActiveUser(sub_page); 492} 493 494void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() { 495 chrome::ScopedTabbedBrowserDisplayer displayer( 496 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); 497 chrome::ShowPolicy(displayer.browser()); 498} 499 500void SystemTrayDelegateChromeOS::ShowSupervisedUserInfo() { 501 // TODO(antrim): find out what should we show in this case. 502 // http://crbug.com/229762 503} 504 505void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() { 506 ash::user::LoginStatus status = GetUserLoginStatus(); 507 if (status == ash::user::LOGGED_IN_NONE || 508 status == ash::user::LOGGED_IN_LOCKED) { 509 scoped_refptr<chromeos::HelpAppLauncher> help_app( 510 new chromeos::HelpAppLauncher(GetNativeWindow())); 511 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE); 512 } else { 513 chrome::ScopedTabbedBrowserDisplayer displayer( 514 ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); 515 chrome::ShowSingletonTab(displayer.browser(), 516 GURL(chrome::kLearnMoreEnterpriseURL)); 517 } 518} 519 520void SystemTrayDelegateChromeOS::ShowUserLogin() { 521 ash::Shell* shell = ash::Shell::GetInstance(); 522 if (!shell->delegate()->IsMultiProfilesEnabled()) 523 return; 524 525 // Only regular users could add other users to current session. 526 if (UserManager::Get()->GetActiveUser()->GetType() != 527 user_manager::USER_TYPE_REGULAR) { 528 return; 529 } 530 531 if (static_cast<int>(UserManager::Get()->GetLoggedInUsers().size()) >= 532 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers()) 533 return; 534 535 // Launch sign in screen to add another user to current session. 536 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) { 537 // Don't show dialog if any logged in user in multi-profiles session 538 // dismissed it. 539 bool show_intro = true; 540 const user_manager::UserList logged_in_users = 541 UserManager::Get()->GetLoggedInUsers(); 542 for (user_manager::UserList::const_iterator it = logged_in_users.begin(); 543 it != logged_in_users.end(); 544 ++it) { 545 show_intro &= !multi_user_util::GetProfileFromUserID( 546 multi_user_util::GetUserIDFromEmail((*it)->email())) 547 ->GetPrefs() 548 ->GetBoolean(prefs::kMultiProfileNeverShowIntro); 549 if (!show_intro) 550 break; 551 } 552 if (show_intro) { 553 base::Callback<void(bool)> on_accept = 554 base::Bind(&OnAcceptMultiprofilesIntro); 555 ShowMultiprofilesIntroDialog(on_accept); 556 } else { 557 UserAddingScreen::Get()->Start(); 558 } 559 } 560} 561 562bool SystemTrayDelegateChromeOS::ShowSpringChargerReplacementDialog() { 563 if (!ChargerReplacementDialog::ShouldShowDialog()) 564 return false; 565 566 ChargerReplacementDialog* dialog = 567 new ChargerReplacementDialog(GetNativeWindow()); 568 dialog->Show(); 569 return true; 570} 571 572bool SystemTrayDelegateChromeOS::IsSpringChargerReplacementDialogVisible() { 573 return ChargerReplacementDialog::IsDialogVisible(); 574} 575 576bool SystemTrayDelegateChromeOS::HasUserConfirmedSafeSpringCharger() { 577 return ChargerReplacementHandler::GetChargerStatusPref() == 578 ChargerReplacementHandler::CONFIRM_SAFE_CHARGER; 579} 580 581void SystemTrayDelegateChromeOS::ShutDown() { 582 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown(); 583} 584 585void SystemTrayDelegateChromeOS::SignOut() { 586 chrome::AttemptUserExit(); 587} 588 589void SystemTrayDelegateChromeOS::RequestLockScreen() { 590 // TODO(antrim) : additional logging for crbug/173178 591 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate"; 592 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); 593} 594 595void SystemTrayDelegateChromeOS::RequestRestartForUpdate() { 596 // We expect that UpdateEngine is in "Reboot for update" state now. 597 chrome::NotifyAndTerminate(true /* fast path */); 598} 599 600void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices( 601 ash::BluetoothDeviceList* list) { 602 device::BluetoothAdapter::DeviceList devices = 603 bluetooth_adapter_->GetDevices(); 604 for (size_t i = 0; i < devices.size(); ++i) { 605 device::BluetoothDevice* device = devices[i]; 606 ash::BluetoothDeviceInfo info; 607 info.address = device->GetAddress(); 608 info.display_name = device->GetName(); 609 info.connected = device->IsConnected(); 610 info.connecting = device->IsConnecting(); 611 info.paired = device->IsPaired(); 612 list->push_back(info); 613 } 614} 615 616void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() { 617 if (GetBluetoothDiscovering()) { 618 LOG(WARNING) << "Already have active Bluetooth device discovery session."; 619 return; 620 } 621 VLOG(1) << "Requesting new Bluetooth device discovery session."; 622 should_run_bluetooth_discovery_ = true; 623 bluetooth_adapter_->StartDiscoverySession( 624 base::Bind(&SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession, 625 weak_ptr_factory_.GetWeakPtr()), 626 base::Bind(&BluetoothSetDiscoveringError)); 627} 628 629void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() { 630 should_run_bluetooth_discovery_ = false; 631 if (!GetBluetoothDiscovering()) { 632 LOG(WARNING) << "No active Bluetooth device discovery session."; 633 return; 634 } 635 VLOG(1) << "Stopping Bluetooth device discovery session."; 636 bluetooth_discovery_session_->Stop( 637 base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError)); 638} 639 640void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice( 641 const std::string& address) { 642 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); 643 if (!device || device->IsConnecting() || 644 (device->IsConnected() && device->IsPaired())) { 645 return; 646 } 647 if (device->IsPaired() && !device->IsConnectable()) 648 return; 649 if (device->IsPaired() || !device->IsPairable()) { 650 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( 651 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE); 652 device->Connect(NULL, 653 base::Bind(&base::DoNothing), 654 base::Bind(&BluetoothDeviceConnectError)); 655 } else { // Show paring dialog for the unpaired device. 656 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( 657 ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE); 658 BluetoothPairingDialog* dialog = 659 new BluetoothPairingDialog(GetNativeWindow(), device); 660 // The dialog deletes itself on close. 661 dialog->Show(); 662 } 663} 664 665bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() { 666 return bluetooth_adapter_->IsDiscovering(); 667} 668 669void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) { 670 input_method::InputMethodManager* manager = 671 input_method::InputMethodManager::Get(); 672 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 673 input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod(); 674 ExtractIMEInfo(ime, *util, info); 675 info->selected = true; 676} 677 678void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) { 679 input_method::InputMethodManager* manager = 680 input_method::InputMethodManager::Get(); 681 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 682 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors( 683 manager->GetActiveInputMethods()); 684 std::string current = manager->GetCurrentInputMethod().id(); 685 for (size_t i = 0; i < ime_descriptors->size(); i++) { 686 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i); 687 ash::IMEInfo info; 688 ExtractIMEInfo(ime, *util, &info); 689 info.selected = ime.id() == current; 690 list->push_back(info); 691 } 692} 693 694void SystemTrayDelegateChromeOS::GetCurrentIMEProperties( 695 ash::IMEPropertyInfoList* list) { 696 ash::ime::InputMethodMenuItemList menu_list = 697 ash::ime::InputMethodMenuManager::GetInstance()-> 698 GetCurrentInputMethodMenuItemList(); 699 for (size_t i = 0; i < menu_list.size(); ++i) { 700 ash::IMEPropertyInfo property; 701 property.key = menu_list[i].key; 702 property.name = base::UTF8ToUTF16(menu_list[i].label); 703 property.selected = menu_list[i].is_selection_item_checked; 704 list->push_back(property); 705 } 706} 707 708void SystemTrayDelegateChromeOS::SwitchIME(const std::string& ime_id) { 709 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id); 710} 711 712void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string& key) { 713 input_method::InputMethodManager::Get()->ActivateInputMethodMenuItem(key); 714} 715 716void SystemTrayDelegateChromeOS::ShowNetworkConfigure( 717 const std::string& network_id, 718 gfx::NativeWindow parent_window) { 719 NetworkConfigView::Show(network_id, parent_window); 720} 721 722bool SystemTrayDelegateChromeOS::EnrollNetwork( 723 const std::string& network_id, 724 gfx::NativeWindow parent_window) { 725 return enrollment::CreateDialog(network_id, parent_window); 726} 727 728void SystemTrayDelegateChromeOS::ManageBluetoothDevices() { 729 content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage")); 730 std::string sub_page = 731 std::string(chrome::kSearchSubPage) + "#" + 732 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH); 733 ShowSettingsSubPageForActiveUser(sub_page); 734} 735 736void SystemTrayDelegateChromeOS::ToggleBluetooth() { 737 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(), 738 base::Bind(&base::DoNothing), 739 base::Bind(&BluetoothPowerFailure)); 740} 741 742void SystemTrayDelegateChromeOS::ShowMobileSimDialog() { 743 SimDialogDelegate::ShowDialog(GetNativeWindow(), 744 SimDialogDelegate::SIM_DIALOG_UNLOCK); 745} 746 747void SystemTrayDelegateChromeOS::ShowMobileSetupDialog( 748 const std::string& service_path) { 749 MobileSetupDialog::Show(service_path); 750} 751 752void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog( 753 const std::string& type) { 754 if (type == shill::kTypeCellular) { 755 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); 756 return; 757 } 758 NetworkConfigView::ShowForType(type, GetNativeWindow()); 759} 760 761bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() { 762 return bluetooth_adapter_->IsPresent(); 763} 764 765bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() { 766 return bluetooth_adapter_->IsPowered(); 767} 768 769bool SystemTrayDelegateChromeOS::GetBluetoothDiscovering() { 770 return (bluetooth_discovery_session_.get() && 771 bluetooth_discovery_session_->IsActive()); 772} 773 774void SystemTrayDelegateChromeOS::ChangeProxySettings() { 775 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE); 776 LoginDisplayHostImpl::default_host()->OpenProxySettings(); 777} 778 779ash::VolumeControlDelegate* 780SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const { 781 return volume_control_delegate_.get(); 782} 783 784void SystemTrayDelegateChromeOS::SetVolumeControlDelegate( 785 scoped_ptr<ash::VolumeControlDelegate> delegate) { 786 volume_control_delegate_.swap(delegate); 787} 788 789bool SystemTrayDelegateChromeOS::GetSessionStartTime( 790 base::TimeTicks* session_start_time) { 791 *session_start_time = session_start_time_; 792 return have_session_start_time_; 793} 794 795bool SystemTrayDelegateChromeOS::GetSessionLengthLimit( 796 base::TimeDelta* session_length_limit) { 797 *session_length_limit = session_length_limit_; 798 return have_session_length_limit_; 799} 800 801int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() { 802 return l10n_util::GetLocalizedContentsWidthInPixels( 803 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS); 804} 805 806void SystemTrayDelegateChromeOS::ActiveUserWasChanged() { 807 GetSystemTrayNotifier()->NotifyUserUpdate(); 808} 809 810bool SystemTrayDelegateChromeOS::IsSearchKeyMappedToCapsLock() { 811 return search_key_mapped_to_ == input_method::kCapsLockKey; 812} 813 814ash::tray::UserAccountsDelegate* 815SystemTrayDelegateChromeOS::GetUserAccountsDelegate( 816 const std::string& user_id) { 817 if (!accounts_delegates_.contains(user_id)) { 818 const user_manager::User* user = UserManager::Get()->FindUser(user_id); 819 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(user); 820 CHECK(user_profile); 821 accounts_delegates_.set( 822 user_id, 823 scoped_ptr<ash::tray::UserAccountsDelegate>( 824 new UserAccountsDelegateChromeOS(user_profile))); 825 } 826 return accounts_delegates_.get(user_id); 827} 828 829ash::SystemTray* SystemTrayDelegateChromeOS::GetPrimarySystemTray() { 830 return ash::Shell::GetInstance()->GetPrimarySystemTray(); 831} 832 833ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() { 834 return ash::Shell::GetInstance()->system_tray_notifier(); 835} 836 837void SystemTrayDelegateChromeOS::SetProfile(Profile* profile) { 838 // Stop observing the AppWindowRegistry of the current |user_profile_|. 839 StopObservingAppWindowRegistry(); 840 841 user_profile_ = profile; 842 843 // Start observing the AppWindowRegistry of the newly set |user_profile_|. 844 apps::AppWindowRegistry::Get(user_profile_)->AddObserver(this); 845 846 PrefService* prefs = profile->GetPrefs(); 847 user_pref_registrar_.reset(new PrefChangeRegistrar); 848 user_pref_registrar_->Init(prefs); 849 user_pref_registrar_->Add( 850 prefs::kUse24HourClock, 851 base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType, 852 base::Unretained(this))); 853 user_pref_registrar_->Add( 854 prefs::kLanguageRemapSearchKeyTo, 855 base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged, 856 base::Unretained(this))); 857 user_pref_registrar_->Add( 858 prefs::kShowLogoutButtonInTray, 859 base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray, 860 base::Unretained(this))); 861 user_pref_registrar_->Add( 862 prefs::kLogoutDialogDurationMs, 863 base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration, 864 base::Unretained(this))); 865 user_pref_registrar_->Add( 866 prefs::kAccessibilityLargeCursorEnabled, 867 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, 868 base::Unretained(this), 869 ash::A11Y_NOTIFICATION_NONE)); 870 user_pref_registrar_->Add( 871 prefs::kAccessibilityAutoclickEnabled, 872 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, 873 base::Unretained(this), 874 ash::A11Y_NOTIFICATION_NONE)); 875 user_pref_registrar_->Add( 876 prefs::kShouldAlwaysShowAccessibilityMenu, 877 base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, 878 base::Unretained(this), 879 ash::A11Y_NOTIFICATION_NONE)); 880 user_pref_registrar_->Add( 881 prefs::kPerformanceTracingEnabled, 882 base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing, 883 base::Unretained(this))); 884 885 UpdateClockType(); 886 UpdateShowLogoutButtonInTray(); 887 UpdateLogoutDialogDuration(); 888 UpdatePerformanceTracing(); 889 search_key_mapped_to_ = 890 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo); 891} 892 893bool SystemTrayDelegateChromeOS::UnsetProfile(Profile* profile) { 894 if (profile != user_profile_) 895 return false; 896 user_pref_registrar_.reset(); 897 user_profile_ = NULL; 898 return true; 899} 900 901bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const { 902 return ShouldUse24HourClock(); 903} 904 905bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const { 906 // On login screen and in guest mode owner default is used for 907 // kUse24HourClock preference. 908 const ash::user::LoginStatus status = GetUserLoginStatus(); 909 const CrosSettings* const cros_settings = CrosSettings::Get(); 910 bool system_use_24_hour_clock = true; 911 const bool system_value_found = cros_settings->GetBoolean( 912 kSystemUse24HourClock, &system_use_24_hour_clock); 913 914 if ((status == ash::user::LOGGED_IN_NONE) || !user_pref_registrar_) 915 return (system_value_found 916 ? system_use_24_hour_clock 917 : (base::GetHourClockType() == base::k24HourClock)); 918 919 const PrefService::Preference* user_pref = 920 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock); 921 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue()) 922 return (system_value_found 923 ? system_use_24_hour_clock 924 : (base::GetHourClockType() == base::k24HourClock)); 925 926 bool use_24_hour_clock = true; 927 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock); 928 return use_24_hour_clock; 929} 930 931void SystemTrayDelegateChromeOS::UpdateClockType() { 932 const bool use_24_hour_clock = ShouldUse24HourClock(); 933 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock; 934 GetSystemTrayNotifier()->NotifyDateFormatChanged(); 935 // This also works for enterprise-managed devices because they never have 936 // local owner. 937 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) 938 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock); 939} 940 941void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() { 942 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged( 943 user_pref_registrar_->prefs()->GetBoolean( 944 prefs::kShowLogoutButtonInTray)); 945} 946 947void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() { 948 const int duration_ms = 949 user_pref_registrar_->prefs()->GetInteger(prefs::kLogoutDialogDurationMs); 950 GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged( 951 base::TimeDelta::FromMilliseconds(duration_ms)); 952} 953 954void SystemTrayDelegateChromeOS::UpdateSessionStartTime() { 955 const PrefService* local_state = local_state_registrar_->prefs(); 956 if (local_state->HasPrefPath(prefs::kSessionStartTime)) { 957 have_session_start_time_ = true; 958 session_start_time_ = base::TimeTicks::FromInternalValue( 959 local_state->GetInt64(prefs::kSessionStartTime)); 960 } else { 961 have_session_start_time_ = false; 962 session_start_time_ = base::TimeTicks(); 963 } 964 GetSystemTrayNotifier()->NotifySessionStartTimeChanged(); 965} 966 967void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() { 968 const PrefService* local_state = local_state_registrar_->prefs(); 969 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) { 970 have_session_length_limit_ = true; 971 session_length_limit_ = base::TimeDelta::FromMilliseconds( 972 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit), 973 kSessionLengthLimitMinMs), 974 kSessionLengthLimitMaxMs)); 975 } else { 976 have_session_length_limit_ = false; 977 session_length_limit_ = base::TimeDelta(); 978 } 979 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged(); 980} 981 982void SystemTrayDelegateChromeOS::StopObservingAppWindowRegistry() { 983 if (!user_profile_) 984 return; 985 986 apps::AppWindowRegistry* registry = 987 apps::AppWindowRegistry::Factory::GetForBrowserContext(user_profile_, 988 false); 989 if (registry) 990 registry->RemoveObserver(this); 991} 992 993void SystemTrayDelegateChromeOS::NotifyIfLastWindowClosed() { 994 if (!user_profile_) 995 return; 996 997 BrowserList* browser_list = 998 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 999 for (BrowserList::const_iterator it = browser_list->begin(); 1000 it != browser_list->end(); 1001 ++it) { 1002 if ((*it)->profile()->IsSameProfile(user_profile_)) { 1003 // The current user has at least one open browser window. 1004 return; 1005 } 1006 } 1007 1008 if (!apps::AppWindowRegistry::Get(user_profile_)->app_windows().empty()) { 1009 // The current user has at least one open app window. 1010 return; 1011 } 1012 1013 GetSystemTrayNotifier()->NotifyLastWindowClosed(); 1014} 1015 1016// LoginState::Observer overrides. 1017void SystemTrayDelegateChromeOS::LoggedInStateChanged() { 1018 // It apparently sometimes takes a while after login before the current user 1019 // is recognized as the owner. Make sure that the system-wide clock setting 1020 // is updated when the recognition eventually happens 1021 // (http://crbug.com/278601). 1022 // 1023 // Note that it isn't safe to blindly call UpdateClockType() from this 1024 // method, as LoggedInStateChanged() is also called before the logged-in 1025 // user's profile has actually been loaded (http://crbug.com/317745). The 1026 // system tray's time format is updated at login via SetProfile(). 1027 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) { 1028 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, 1029 ShouldUse24HourClock()); 1030 } 1031} 1032 1033// Overridden from SessionManagerClient::Observer. 1034void SystemTrayDelegateChromeOS::ScreenIsLocked() { 1035 screen_locked_ = true; 1036 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus()); 1037} 1038 1039void SystemTrayDelegateChromeOS::ScreenIsUnlocked() { 1040 screen_locked_ = false; 1041 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus()); 1042} 1043 1044gfx::NativeWindow SystemTrayDelegateChromeOS::GetNativeWindow() const { 1045 bool session_started = ash::Shell::GetInstance() 1046 ->session_state_delegate() 1047 ->IsActiveUserSessionStarted(); 1048 return GetNativeWindowByStatus(GetUserLoginStatus(), session_started); 1049} 1050 1051// content::NotificationObserver implementation. 1052void SystemTrayDelegateChromeOS::Observe( 1053 int type, 1054 const content::NotificationSource& source, 1055 const content::NotificationDetails& details) { 1056 switch (type) { 1057 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { 1058 UpgradeDetector* detector = 1059 content::Source<UpgradeDetector>(source).ptr(); 1060 ash::UpdateObserver::UpdateSeverity severity = 1061 ash::UpdateObserver::UPDATE_NORMAL; 1062 switch (detector->upgrade_notification_stage()) { 1063 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: 1064 severity = ash::UpdateObserver::UPDATE_SEVERE_RED; 1065 break; 1066 1067 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: 1068 severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE; 1069 break; 1070 1071 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: 1072 severity = ash::UpdateObserver::UPDATE_LOW_GREEN; 1073 break; 1074 1075 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW: 1076 default: 1077 severity = ash::UpdateObserver::UPDATE_NORMAL; 1078 break; 1079 } 1080 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity); 1081 break; 1082 } 1083 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: { 1084 // This notification is also sent on login screen when user avatar 1085 // is loaded from file. 1086 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) { 1087 GetSystemTrayNotifier()->NotifyUserUpdate(); 1088 } 1089 break; 1090 } 1091 case chrome::NOTIFICATION_PROFILE_CREATED: { 1092 SetProfile(content::Source<Profile>(source).ptr()); 1093 registrar_->Remove(this, 1094 chrome::NOTIFICATION_PROFILE_CREATED, 1095 content::NotificationService::AllSources()); 1096 break; 1097 } 1098 case chrome::NOTIFICATION_PROFILE_DESTROYED: { 1099 if (UnsetProfile(content::Source<Profile>(source).ptr())) { 1100 registrar_->Remove(this, 1101 chrome::NOTIFICATION_PROFILE_DESTROYED, 1102 content::NotificationService::AllSources()); 1103 } 1104 break; 1105 } 1106 case chrome::NOTIFICATION_SESSION_STARTED: { 1107 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( 1108 GetUserLoginStatus()); 1109 SetProfile(ProfileManager::GetActiveUserProfile()); 1110 break; 1111 } 1112 default: 1113 NOTREACHED(); 1114 } 1115} 1116 1117void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() { 1118 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger( 1119 prefs::kLanguageRemapSearchKeyTo); 1120} 1121 1122void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged( 1123 ash::AccessibilityNotificationVisibility notify) { 1124 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify); 1125} 1126 1127void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() { 1128 if (!user_pref_registrar_) 1129 return; 1130 bool value = user_pref_registrar_->prefs()->GetBoolean( 1131 prefs::kPerformanceTracingEnabled); 1132 GetSystemTrayNotifier()->NotifyTracingModeChanged(value); 1133} 1134 1135// Overridden from InputMethodManager::Observer. 1136void SystemTrayDelegateChromeOS::InputMethodChanged( 1137 input_method::InputMethodManager* manager, 1138 bool show_message) { 1139 GetSystemTrayNotifier()->NotifyRefreshIME(); 1140} 1141 1142// Overridden from InputMethodMenuManager::Observer. 1143void SystemTrayDelegateChromeOS::InputMethodMenuItemChanged( 1144 ash::ime::InputMethodMenuManager* manager) { 1145 GetSystemTrayNotifier()->NotifyRefreshIME(); 1146} 1147 1148// Overridden from CrasAudioHandler::AudioObserver. 1149void SystemTrayDelegateChromeOS::OnOutputVolumeChanged() { 1150 GetSystemTrayNotifier()->NotifyAudioOutputVolumeChanged(); 1151} 1152 1153void SystemTrayDelegateChromeOS::OnOutputMuteChanged() { 1154 GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged(); 1155} 1156 1157void SystemTrayDelegateChromeOS::OnInputGainChanged() { 1158} 1159 1160void SystemTrayDelegateChromeOS::OnInputMuteChanged() { 1161} 1162 1163void SystemTrayDelegateChromeOS::OnAudioNodesChanged() { 1164 GetSystemTrayNotifier()->NotifyAudioNodesChanged(); 1165} 1166 1167void SystemTrayDelegateChromeOS::OnActiveOutputNodeChanged() { 1168 GetSystemTrayNotifier()->NotifyAudioActiveOutputNodeChanged(); 1169} 1170 1171void SystemTrayDelegateChromeOS::OnActiveInputNodeChanged() { 1172 GetSystemTrayNotifier()->NotifyAudioActiveInputNodeChanged(); 1173} 1174 1175// Overridden from BluetoothAdapter::Observer. 1176void SystemTrayDelegateChromeOS::AdapterPresentChanged( 1177 device::BluetoothAdapter* adapter, 1178 bool present) { 1179 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1180} 1181 1182void SystemTrayDelegateChromeOS::AdapterPoweredChanged( 1183 device::BluetoothAdapter* adapter, 1184 bool powered) { 1185 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1186} 1187 1188void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged( 1189 device::BluetoothAdapter* adapter, 1190 bool discovering) { 1191 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged(); 1192} 1193 1194void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter* adapter, 1195 device::BluetoothDevice* device) { 1196 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1197} 1198 1199void SystemTrayDelegateChromeOS::DeviceChanged( 1200 device::BluetoothAdapter* adapter, 1201 device::BluetoothDevice* device) { 1202 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1203} 1204 1205void SystemTrayDelegateChromeOS::DeviceRemoved( 1206 device::BluetoothAdapter* adapter, 1207 device::BluetoothDevice* device) { 1208 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1209} 1210 1211void SystemTrayDelegateChromeOS::OnStartBluetoothDiscoverySession( 1212 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 1213 // If the discovery session was returned after a request to stop discovery 1214 // (e.g. the user dismissed the Bluetooth detailed view before the call 1215 // returned), don't claim the discovery session and let it clean up. 1216 if (!should_run_bluetooth_discovery_) 1217 return; 1218 VLOG(1) << "Claiming new Bluetooth device discovery session."; 1219 bluetooth_discovery_session_ = discovery_session.Pass(); 1220 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged(); 1221} 1222 1223void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() { 1224 policy::BrowserPolicyConnectorChromeOS* connector = 1225 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 1226 std::string enterprise_domain = connector->GetEnterpriseDomain(); 1227 if (enterprise_domain_ != enterprise_domain) { 1228 enterprise_domain_ = enterprise_domain; 1229 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged(); 1230 } 1231} 1232 1233// Overridden from CloudPolicyStore::Observer 1234void SystemTrayDelegateChromeOS::OnStoreLoaded( 1235 policy::CloudPolicyStore* store) { 1236 UpdateEnterpriseDomain(); 1237} 1238 1239void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore* store) { 1240 UpdateEnterpriseDomain(); 1241} 1242 1243// Overridden from ash::SessionStateObserver 1244void SystemTrayDelegateChromeOS::UserAddedToSession( 1245 const std::string& user_id) { 1246 GetSystemTrayNotifier()->NotifyUserAddedToSession(); 1247} 1248 1249// Overridden from chrome::BrowserListObserver. 1250void SystemTrayDelegateChromeOS::OnBrowserRemoved(Browser* browser) { 1251 NotifyIfLastWindowClosed(); 1252} 1253 1254// Overridden from apps::AppWindowRegistry::Observer. 1255void SystemTrayDelegateChromeOS::OnAppWindowRemoved( 1256 apps::AppWindow* app_window) { 1257 NotifyIfLastWindowClosed(); 1258} 1259 1260void SystemTrayDelegateChromeOS::OnAccessibilityStatusChanged( 1261 const AccessibilityStatusEventDetails& details) { 1262 if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN) 1263 accessibility_subscription_.reset(); 1264 else 1265 OnAccessibilityModeChanged(details.notify); 1266} 1267 1268ash::SystemTrayDelegate* CreateSystemTrayDelegate() { 1269 return new SystemTrayDelegateChromeOS(); 1270} 1271 1272} // namespace chromeos 1273