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