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