1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/system/ash_system_tray_delegate.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/session_state_delegate.h" 15 #include "ash/session_state_observer.h" 16 #include "ash/shell.h" 17 #include "ash/shell_delegate.h" 18 #include "ash/shell_window_ids.h" 19 #include "ash/system/bluetooth/bluetooth_observer.h" 20 #include "ash/system/brightness/brightness_observer.h" 21 #include "ash/system/chromeos/network/network_observer.h" 22 #include "ash/system/chromeos/network/network_tray_delegate.h" 23 #include "ash/system/date/clock_observer.h" 24 #include "ash/system/drive/drive_observer.h" 25 #include "ash/system/ime/ime_observer.h" 26 #include "ash/system/logout_button/logout_button_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/tray_caps_lock.h" 32 #include "ash/system/user/login_status.h" 33 #include "ash/system/user/update_observer.h" 34 #include "ash/system/user/user_observer.h" 35 #include "ash/volume_control_delegate.h" 36 #include "ash/wm/lock_state_controller.h" 37 #include "base/bind_helpers.h" 38 #include "base/callback.h" 39 #include "base/chromeos/chromeos_version.h" 40 #include "base/command_line.h" 41 #include "base/logging.h" 42 #include "base/memory/weak_ptr.h" 43 #include "base/prefs/pref_service.h" 44 #include "base/strings/stringprintf.h" 45 #include "base/strings/utf_string_conversions.h" 46 #include "base/time/time.h" 47 #include "chrome/browser/browser_process.h" 48 #include "chrome/browser/chrome_notification_types.h" 49 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 50 #include "chrome/browser/chromeos/accessibility/magnification_manager.h" 51 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h" 52 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h" 53 #include "chrome/browser/chromeos/cros/network_library.h" 54 #include "chrome/browser/chromeos/drive/drive_integration_service.h" 55 #include "chrome/browser/chromeos/drive/job_list.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/user.h" 64 #include "chrome/browser/chromeos/login/user_adding_screen.h" 65 #include "chrome/browser/chromeos/login/user_manager.h" 66 #include "chrome/browser/chromeos/mobile_config.h" 67 #include "chrome/browser/chromeos/options/network_config_view.h" 68 #include "chrome/browser/chromeos/options/network_connect.h" 69 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 70 #include "chrome/browser/chromeos/settings/cros_settings.h" 71 #include "chrome/browser/chromeos/sim_dialog_delegate.h" 72 #include "chrome/browser/chromeos/status/data_promo_notification.h" 73 #include "chrome/browser/chromeos/system/timezone_settings.h" 74 #include "chrome/browser/chromeos/system_key_event_listener.h" 75 #include "chrome/browser/drive/drive_service_interface.h" 76 #include "chrome/browser/feedback/tracing_manager.h" 77 #include "chrome/browser/google/google_util.h" 78 #include "chrome/browser/lifetime/application_lifetime.h" 79 #include "chrome/browser/policy/browser_policy_connector.h" 80 #include "chrome/browser/policy/cloud/cloud_policy_store.h" 81 #include "chrome/browser/profiles/profile_manager.h" 82 #include "chrome/browser/ui/ash/volume_controller_chromeos.h" 83 #include "chrome/browser/ui/browser.h" 84 #include "chrome/browser/ui/browser_finder.h" 85 #include "chrome/browser/ui/chrome_pages.h" 86 #include "chrome/browser/ui/host_desktop.h" 87 #include "chrome/browser/ui/singleton_tabs.h" 88 #include "chrome/browser/ui/tabs/tab_strip_model.h" 89 #include "chrome/browser/upgrade_detector.h" 90 #include "chrome/common/pref_names.h" 91 #include "chrome/common/url_constants.h" 92 #include "chromeos/chromeos_switches.h" 93 #include "chromeos/dbus/dbus_thread_manager.h" 94 #include "chromeos/dbus/power_manager_client.h" 95 #include "chromeos/dbus/session_manager_client.h" 96 #include "chromeos/dbus/system_clock_client.h" 97 #include "chromeos/ime/extension_ime_util.h" 98 #include "chromeos/ime/input_method_manager.h" 99 #include "chromeos/ime/xkeyboard.h" 100 #include "chromeos/login/login_state.h" 101 #include "chromeos/network/network_state.h" 102 #include "chromeos/network/network_state_handler.h" 103 #include "content/public/browser/browser_thread.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 "grit/ash_strings.h" 112 #include "grit/generated_resources.h" 113 #include "grit/locale_settings.h" 114 #include "net/base/escape.h" 115 #include "third_party/cros_system_api/dbus/service_constants.h" 116 #include "ui/base/l10n/l10n_util.h" 117 #include "ui/base/l10n/time_format.h" 118 119 using drive::DriveIntegrationService; 120 using drive::DriveIntegrationServiceFactory; 121 122 namespace chromeos { 123 124 namespace { 125 126 // The minimum session length limit that can be set. 127 const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds. 128 129 // The maximum session length limit that can be set. 130 const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours. 131 132 const char kDisplaySettingsSubPageName[] = "display"; 133 const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan"; 134 135 void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, 136 const input_method::InputMethodUtil& util, 137 ash::IMEInfo* info) { 138 info->id = ime.id(); 139 info->name = util.GetInputMethodLongName(ime); 140 info->medium_name = util.GetInputMethodMediumName(ime); 141 info->short_name = util.GetInputMethodShortName(ime); 142 info->third_party = extension_ime_util::IsExtensionIME(ime.id()); 143 } 144 145 gfx::NativeWindow GetNativeWindowByStatus( 146 ash::user::LoginStatus login_status) { 147 int container_id = 148 (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. 158 bool 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. 185 bool 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. 197 ash::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 208 void BluetoothPowerFailure() { 209 // TODO(sad): Show an error bubble? 210 } 211 212 void BluetoothDiscoveryFailure() { 213 // TODO(sad): Show an error bubble? 214 } 215 216 void BluetoothSetDiscoveringError() { 217 LOG(ERROR) << "BluetoothSetDiscovering failed."; 218 } 219 220 void BluetoothDeviceConnectError( 221 device::BluetoothDevice::ConnectErrorCode error_code) { 222 // TODO(sad): Do something? 223 } 224 225 ash::NetworkObserver::NetworkType NetworkTypeForCellular( 226 const CellularNetwork* cellular) { 227 if (cellular->network_technology() == NETWORK_TECHNOLOGY_LTE || 228 cellular->network_technology() == NETWORK_TECHNOLOGY_LTE_ADVANCED) 229 return ash::NetworkObserver::NETWORK_CELLULAR_LTE; 230 return ash::NetworkObserver::NETWORK_CELLULAR; 231 } 232 233 class SystemTrayDelegate : public ash::SystemTrayDelegate, 234 public PowerManagerClient::Observer, 235 public SessionManagerClient::Observer, 236 public NetworkLibrary::NetworkManagerObserver, 237 public drive::JobListObserver, 238 public content::NotificationObserver, 239 public input_method::InputMethodManager::Observer, 240 public system::TimezoneSettings::Observer, 241 public chromeos::LoginState::Observer, 242 public chromeos::SystemClockClient::Observer, 243 public device::BluetoothAdapter::Observer, 244 public SystemKeyEventListener::CapsLockObserver, 245 public ash::NetworkTrayDelegate, 246 public policy::CloudPolicyStore::Observer, 247 public ash::SessionStateObserver { 248 public: 249 SystemTrayDelegate() 250 : ui_weak_ptr_factory_( 251 new base::WeakPtrFactory<SystemTrayDelegate>(this)), 252 user_profile_(NULL), 253 clock_type_(base::GetHourClockType()), 254 search_key_mapped_to_(input_method::kSearchKey), 255 screen_locked_(false), 256 have_session_start_time_(false), 257 have_session_length_limit_(false), 258 data_promo_notification_(new DataPromoNotification()), 259 cellular_activating_(false), 260 cellular_out_of_credits_(false), 261 volume_control_delegate_(new VolumeController()) { 262 // Register notifications on construction so that events such as 263 // PROFILE_CREATED do not get missed if they happen before Initialize(). 264 registrar_.reset(new content::NotificationRegistrar); 265 registrar_->Add(this, 266 chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 267 content::NotificationService::AllSources()); 268 registrar_->Add(this, 269 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, 270 content::NotificationService::AllSources()); 271 if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) { 272 registrar_->Add(this, 273 chrome::NOTIFICATION_SESSION_STARTED, 274 content::NotificationService::AllSources()); 275 } 276 registrar_->Add(this, 277 chrome::NOTIFICATION_PROFILE_CREATED, 278 content::NotificationService::AllSources()); 279 registrar_->Add(this, 280 chrome::NOTIFICATION_PROFILE_DESTROYED, 281 content::NotificationService::AllSources()); 282 registrar_->Add( 283 this, 284 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER, 285 content::NotificationService::AllSources()); 286 registrar_->Add( 287 this, 288 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK, 289 content::NotificationService::AllSources()); 290 registrar_->Add( 291 this, 292 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, 293 content::NotificationService::AllSources()); 294 } 295 296 virtual void Initialize() OVERRIDE { 297 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); 298 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); 299 300 NetworkLibrary* crosnet = NetworkLibrary::Get(); 301 crosnet->AddNetworkManagerObserver(this); 302 OnNetworkManagerChanged(crosnet); 303 304 input_method::InputMethodManager::Get()->AddObserver(this); 305 UpdateClockType(); 306 307 system::TimezoneSettings::GetInstance()->AddObserver(this); 308 DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(this); 309 310 if (SystemKeyEventListener::GetInstance()) 311 SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this); 312 313 device::BluetoothAdapterFactory::GetAdapter( 314 base::Bind(&SystemTrayDelegate::InitializeOnAdapterReady, 315 ui_weak_ptr_factory_->GetWeakPtr())); 316 317 ash::Shell::GetInstance()->session_state_delegate()-> 318 AddSessionStateObserver(this); 319 320 if (LoginState::IsInitialized()) 321 LoginState::Get()->AddObserver(this); 322 } 323 324 virtual void Shutdown() OVERRIDE { 325 data_promo_notification_.reset(); 326 } 327 328 void InitializeOnAdapterReady( 329 scoped_refptr<device::BluetoothAdapter> adapter) { 330 bluetooth_adapter_ = adapter; 331 CHECK(bluetooth_adapter_.get()); 332 bluetooth_adapter_->AddObserver(this); 333 334 local_state_registrar_.reset(new PrefChangeRegistrar); 335 local_state_registrar_->Init(g_browser_process->local_state()); 336 337 UpdateSessionStartTime(); 338 UpdateSessionLengthLimit(); 339 340 local_state_registrar_->Add( 341 prefs::kSessionStartTime, 342 base::Bind(&SystemTrayDelegate::UpdateSessionStartTime, 343 base::Unretained(this))); 344 local_state_registrar_->Add( 345 prefs::kSessionLengthLimit, 346 base::Bind(&SystemTrayDelegate::UpdateSessionLengthLimit, 347 base::Unretained(this))); 348 349 policy::BrowserPolicyConnector* policy_connector = 350 g_browser_process->browser_policy_connector(); 351 policy::DeviceCloudPolicyManagerChromeOS* policy_manager = 352 policy_connector->GetDeviceCloudPolicyManager(); 353 if (policy_manager) 354 policy_manager->core()->store()->AddObserver(this); 355 UpdateEnterpriseDomain(); 356 } 357 358 virtual ~SystemTrayDelegate() { 359 // Unregister PrefChangeRegistrars. 360 local_state_registrar_.reset(); 361 user_pref_registrar_.reset(); 362 363 // Unregister content notifications befure destroying any components. 364 registrar_.reset(); 365 366 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); 367 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); 368 DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(this); 369 NetworkLibrary* crosnet = NetworkLibrary::Get(); 370 if (crosnet) 371 crosnet->RemoveNetworkManagerObserver(this); 372 input_method::InputMethodManager::Get()->RemoveObserver(this); 373 system::TimezoneSettings::GetInstance()->RemoveObserver(this); 374 if (SystemKeyEventListener::GetInstance()) 375 SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this); 376 bluetooth_adapter_->RemoveObserver(this); 377 ash::Shell::GetInstance()->session_state_delegate()-> 378 RemoveSessionStateObserver(this); 379 LoginState::Get()->RemoveObserver(this); 380 381 // Stop observing Drive operations. 382 UnobserveDriveUpdates(); 383 384 policy::DeviceCloudPolicyManagerChromeOS* policy_manager = 385 g_browser_process->browser_policy_connector()-> 386 GetDeviceCloudPolicyManager(); 387 if (policy_manager) 388 policy_manager->core()->store()->RemoveObserver(this); 389 } 390 391 // Overridden from ash::SystemTrayDelegate: 392 virtual bool GetTrayVisibilityOnStartup() OVERRIDE { 393 // In case of OOBE / sign in screen tray will be shown later. 394 return LoginState::Get()->IsUserLoggedIn(); 395 } 396 397 virtual ash::user::LoginStatus GetUserLoginStatus() const OVERRIDE { 398 // Map ChromeOS specific LOGGED_IN states to Ash LOGGED_IN states. 399 LoginState::LoggedInState state = LoginState::Get()->GetLoggedInState(); 400 if (state == LoginState::LOGGED_IN_OOBE || 401 state == LoginState::LOGGED_IN_NONE) { 402 return ash::user::LOGGED_IN_NONE; 403 } 404 if (screen_locked_) 405 return ash::user::LOGGED_IN_LOCKED; 406 407 LoginState::LoggedInUserType user_type = 408 LoginState::Get()->GetLoggedInUserType(); 409 switch (user_type) { 410 case LoginState::LOGGED_IN_USER_NONE: 411 return ash::user::LOGGED_IN_NONE; 412 case LoginState::LOGGED_IN_USER_REGULAR: 413 return ash::user::LOGGED_IN_USER; 414 case LoginState::LOGGED_IN_USER_OWNER: 415 return ash::user::LOGGED_IN_OWNER; 416 case LoginState::LOGGED_IN_USER_GUEST: 417 return ash::user::LOGGED_IN_GUEST; 418 case LoginState::LOGGED_IN_USER_RETAIL_MODE: 419 return ash::user::LOGGED_IN_RETAIL_MODE; 420 case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT: 421 return ash::user::LOGGED_IN_PUBLIC; 422 case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED: 423 return ash::user::LOGGED_IN_LOCALLY_MANAGED; 424 case LoginState::LOGGED_IN_USER_KIOSK_APP: 425 return ash::user::LOGGED_IN_KIOSK_APP; 426 } 427 NOTREACHED(); 428 return ash::user::LOGGED_IN_NONE; 429 } 430 431 virtual bool IsOobeCompleted() const OVERRIDE { 432 if (!base::chromeos::IsRunningOnChromeOS() && 433 LoginState::Get()->GetLoggedInState() == LoginState::LOGGED_IN_ACTIVE) 434 return true; 435 return StartupUtils::IsOobeCompleted(); 436 } 437 438 virtual void ChangeProfilePicture() OVERRIDE { 439 content::RecordAction( 440 content::UserMetricsAction("OpenChangeProfilePictureDialog")); 441 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), 442 chrome::kChangeProfilePictureSubPage); 443 } 444 445 virtual const std::string GetEnterpriseDomain() const OVERRIDE { 446 return enterprise_domain_; 447 } 448 449 virtual const string16 GetEnterpriseMessage() const OVERRIDE { 450 if (GetEnterpriseDomain().empty()) 451 return string16(); 452 return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE, 453 UTF8ToUTF16(GetEnterpriseDomain())); 454 } 455 456 virtual const std::string GetLocallyManagedUserManager() const OVERRIDE { 457 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) 458 return std::string(); 459 return UserManager::Get()->GetManagerDisplayEmailForManagedUser( 460 chromeos::UserManager::Get()->GetActiveUser()->email()); 461 } 462 463 virtual const string16 GetLocallyManagedUserManagerName() const OVERRIDE { 464 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) 465 return string16(); 466 return UserManager::Get()->GetManagerDisplayNameForManagedUser( 467 chromeos::UserManager::Get()->GetActiveUser()->email()); 468 } 469 470 virtual const string16 GetLocallyManagedUserMessage() const OVERRIDE { 471 if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) 472 return string16(); 473 return l10n_util::GetStringFUTF16( 474 IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE, 475 UTF8ToUTF16(GetLocallyManagedUserManager())); 476 } 477 478 virtual bool SystemShouldUpgrade() const OVERRIDE { 479 return UpgradeDetector::GetInstance()->notify_upgrade(); 480 } 481 482 virtual base::HourClockType GetHourClockType() const OVERRIDE { 483 return clock_type_; 484 } 485 486 virtual void ShowSettings() OVERRIDE { 487 chrome::ShowSettings(GetAppropriateBrowser()); 488 } 489 490 virtual bool ShouldShowSettings() OVERRIDE { 491 return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings(); 492 } 493 494 virtual void ShowDateSettings() OVERRIDE { 495 content::RecordAction(content::UserMetricsAction("ShowDateOptions")); 496 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + 497 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME); 498 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page); 499 } 500 501 virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE { 502 if (!LoginState::Get()->IsUserLoggedIn()) 503 return; 504 network_connect::ShowNetworkSettings(service_path); 505 } 506 507 virtual void ShowBluetoothSettings() OVERRIDE { 508 // TODO(sad): Make this work. 509 } 510 511 virtual void ShowDisplaySettings() OVERRIDE { 512 content::RecordAction(content::UserMetricsAction("ShowDisplayOptions")); 513 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), 514 kDisplaySettingsSubPageName); 515 } 516 517 virtual void ShowChromeSlow() OVERRIDE { 518 chrome::ShowSlow(GetAppropriateBrowser()); 519 } 520 521 virtual bool ShouldShowDisplayNotification() OVERRIDE { 522 // Packaged app is not counted as 'last active', so if a browser opening the 523 // display settings is in background of a packaged app, it will return true. 524 // TODO(mukai): fix this. 525 Browser* active_browser = chrome::FindLastActiveWithHostDesktopType( 526 chrome::HOST_DESKTOP_TYPE_ASH); 527 if (!active_browser) 528 return true; 529 530 content::WebContents* active_contents = 531 active_browser->tab_strip_model()->GetActiveWebContents(); 532 if (!active_contents) 533 return true; 534 535 GURL visible_url = active_contents->GetLastCommittedURL(); 536 std::string display_settings_url = 537 std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName; 538 std::string display_overscan_url = 539 std::string(chrome::kChromeUISettingsURL) + 540 kDisplayOverscanSettingsSubPageName; 541 return (visible_url.spec() != display_settings_url) && 542 (visible_url.spec() != display_overscan_url); 543 } 544 545 virtual void ShowDriveSettings() OVERRIDE { 546 // TODO(hshi): Open the drive-specific settings page once we put it in. 547 // For now just show search result for downoads settings. 548 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + 549 l10n_util::GetStringUTF8(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME); 550 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page); 551 } 552 553 virtual void ShowIMESettings() OVERRIDE { 554 content::RecordAction( 555 content::UserMetricsAction("OpenLanguageOptionsDialog")); 556 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), 557 chrome::kLanguageOptionsSubPage); 558 } 559 560 virtual void ShowHelp() OVERRIDE { 561 chrome::ShowHelp(GetAppropriateBrowser(), chrome::HELP_SOURCE_MENU); 562 } 563 564 virtual void ShowAccessibilityHelp() OVERRIDE { 565 accessibility::ShowAccessibilityHelp(GetAppropriateBrowser()); 566 } 567 568 virtual void ShowAccessibilitySettings() OVERRIDE { 569 content::RecordAction( 570 content::UserMetricsAction("ShowAccessibilitySettings")); 571 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + 572 l10n_util::GetStringUTF8( 573 IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY); 574 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page); 575 } 576 577 virtual void ShowPublicAccountInfo() OVERRIDE { 578 chrome::ShowPolicy(GetAppropriateBrowser()); 579 } 580 581 virtual void ShowLocallyManagedUserInfo() OVERRIDE { 582 // TODO(antrim): find out what should we show in this case. 583 // http://crbug.com/229762 584 } 585 586 virtual void ShowEnterpriseInfo() OVERRIDE { 587 ash::user::LoginStatus status = GetUserLoginStatus(); 588 if (status == ash::user::LOGGED_IN_NONE || 589 status == ash::user::LOGGED_IN_LOCKED) { 590 scoped_refptr<chromeos::HelpAppLauncher> help_app( 591 new chromeos::HelpAppLauncher(GetNativeWindow())); 592 help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE); 593 } else { 594 GURL url(google_util::StringAppendGoogleLocaleParam( 595 chrome::kLearnMoreEnterpriseURL)); 596 chrome::ShowSingletonTab(GetAppropriateBrowser(), url); 597 } 598 } 599 600 virtual void ShowUserLogin() OVERRIDE { 601 if (!ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) 602 return; 603 604 // Only regular users could add other users to current session. 605 if (UserManager::Get()->GetActiveUser()->GetType() != 606 User::USER_TYPE_REGULAR) { 607 return; 608 } 609 610 // TODO(nkostylev): Show some UI messages why no more users could be added 611 // to this session. http://crbug.com/230863 612 // We limit list of logged in users to 3 due to memory constraints. 613 // TODO(nkostylev): Adjust this limitation based on device capabilites. 614 // http://crbug.com/230865 615 if (UserManager::Get()->GetLoggedInUsers().size() >= 3) 616 return; 617 618 // Launch sign in screen to add another user to current session. 619 if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) 620 UserAddingScreen::Get()->Start(); 621 } 622 623 virtual void ShutDown() OVERRIDE { 624 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown(); 625 } 626 627 virtual void SignOut() OVERRIDE { 628 chrome::AttemptUserExit(); 629 } 630 631 virtual void RequestLockScreen() OVERRIDE { 632 // TODO(antrim) : additional logging for crbug/173178 633 LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate"; 634 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); 635 } 636 637 virtual void RequestRestartForUpdate() OVERRIDE { 638 // We expect that UpdateEngine is in "Reboot for update" state now. 639 chrome::NotifyAndTerminate(true /* fast path */); 640 } 641 642 virtual void GetAvailableBluetoothDevices( 643 ash::BluetoothDeviceList* list) OVERRIDE { 644 device::BluetoothAdapter::DeviceList devices = 645 bluetooth_adapter_->GetDevices(); 646 for (size_t i = 0; i < devices.size(); ++i) { 647 device::BluetoothDevice* device = devices[i]; 648 ash::BluetoothDeviceInfo info; 649 info.address = device->GetAddress(); 650 info.display_name = device->GetName(); 651 info.connected = device->IsConnected(); 652 info.connecting = device->IsConnecting(); 653 info.paired = device->IsPaired(); 654 list->push_back(info); 655 } 656 } 657 658 virtual void BluetoothStartDiscovering() OVERRIDE { 659 bluetooth_adapter_->StartDiscovering( 660 base::Bind(&base::DoNothing), 661 base::Bind(&BluetoothSetDiscoveringError)); 662 } 663 664 virtual void BluetoothStopDiscovering() OVERRIDE { 665 bluetooth_adapter_->StopDiscovering( 666 base::Bind(&base::DoNothing), 667 base::Bind(&BluetoothSetDiscoveringError)); 668 } 669 670 virtual void ConnectToBluetoothDevice(const std::string& address) OVERRIDE { 671 device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); 672 if (!device || device->IsConnecting() || 673 (device->IsConnected() && device->IsPaired())) { 674 return; 675 } 676 if (device->IsPaired() && !device->IsConnectable()) 677 return; 678 if (device->IsPaired() || !device->IsPairable()) { 679 device->Connect( 680 NULL, 681 base::Bind(&base::DoNothing), 682 base::Bind(&BluetoothDeviceConnectError)); 683 } else { // Show paring dialog for the unpaired device. 684 BluetoothPairingDialog* dialog = 685 new BluetoothPairingDialog(GetNativeWindow(), device); 686 // The dialog deletes itself on close. 687 dialog->Show(); 688 } 689 } 690 691 virtual bool IsBluetoothDiscovering() OVERRIDE { 692 return bluetooth_adapter_->IsDiscovering(); 693 } 694 695 virtual void GetCurrentIME(ash::IMEInfo* info) OVERRIDE { 696 input_method::InputMethodManager* manager = 697 input_method::InputMethodManager::Get(); 698 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 699 input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod(); 700 ExtractIMEInfo(ime, *util, info); 701 info->selected = true; 702 } 703 704 virtual void GetAvailableIMEList(ash::IMEInfoList* list) OVERRIDE { 705 input_method::InputMethodManager* manager = 706 input_method::InputMethodManager::Get(); 707 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 708 scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors( 709 manager->GetActiveInputMethods()); 710 std::string current = manager->GetCurrentInputMethod().id(); 711 for (size_t i = 0; i < ime_descriptors->size(); i++) { 712 input_method::InputMethodDescriptor& ime = ime_descriptors->at(i); 713 ash::IMEInfo info; 714 ExtractIMEInfo(ime, *util, &info); 715 info.selected = ime.id() == current; 716 list->push_back(info); 717 } 718 } 719 720 virtual void GetCurrentIMEProperties( 721 ash::IMEPropertyInfoList* list) OVERRIDE { 722 input_method::InputMethodManager* manager = 723 input_method::InputMethodManager::Get(); 724 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 725 input_method::InputMethodPropertyList properties = 726 manager->GetCurrentInputMethodProperties(); 727 for (size_t i = 0; i < properties.size(); ++i) { 728 ash::IMEPropertyInfo property; 729 property.key = properties[i].key; 730 property.name = util->TranslateString(properties[i].label); 731 property.selected = properties[i].is_selection_item_checked; 732 list->push_back(property); 733 } 734 } 735 736 virtual void SwitchIME(const std::string& ime_id) OVERRIDE { 737 input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id); 738 } 739 740 virtual void ActivateIMEProperty(const std::string& key) OVERRIDE { 741 input_method::InputMethodManager::Get()-> 742 ActivateInputMethodProperty(key); 743 } 744 745 virtual void CancelDriveOperation(int32 operation_id) OVERRIDE { 746 DriveIntegrationService* integration_service = 747 FindDriveIntegrationService(); 748 if (!integration_service) 749 return; 750 751 integration_service->job_list()->CancelJob(operation_id); 752 } 753 754 virtual void GetDriveOperationStatusList( 755 ash::DriveOperationStatusList* list) OVERRIDE { 756 DriveIntegrationService* integration_service = 757 FindDriveIntegrationService(); 758 if (!integration_service) 759 return; 760 761 *list = ConvertToDriveStatusList( 762 integration_service->job_list()->GetJobInfoList()); 763 } 764 765 virtual void ConfigureNetwork(const std::string& network_id) OVERRIDE { 766 network_connect::HandleUnconfiguredNetwork(network_id, GetNativeWindow()); 767 } 768 769 virtual void EnrollOrConfigureNetwork( 770 const std::string& network_id, 771 gfx::NativeWindow parent_window) OVERRIDE { 772 if (network_connect::EnrollNetwork(network_id, parent_window)) 773 return; 774 network_connect::HandleUnconfiguredNetwork(network_id, parent_window); 775 } 776 777 virtual void ManageBluetoothDevices() OVERRIDE { 778 content::RecordAction( 779 content::UserMetricsAction("ShowBluetoothSettingsPage")); 780 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + 781 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH); 782 chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page); 783 } 784 785 virtual void ToggleBluetooth() OVERRIDE { 786 bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(), 787 base::Bind(&base::DoNothing), 788 base::Bind(&BluetoothPowerFailure)); 789 } 790 791 virtual void ShowMobileSimDialog() OVERRIDE { 792 SimDialogDelegate::ShowDialog(GetNativeWindow(), 793 SimDialogDelegate::SIM_DIALOG_UNLOCK); 794 } 795 796 virtual void ShowMobileSetup(const std::string& network_id) OVERRIDE { 797 network_connect::ShowMobileSetup(network_id); 798 } 799 800 virtual void ShowOtherWifi() OVERRIDE { 801 NetworkConfigView::ShowForType(flimflam::kTypeWifi, GetNativeWindow()); 802 } 803 804 virtual void ShowOtherVPN() OVERRIDE { 805 NetworkConfigView::ShowForType(flimflam::kTypeVPN, GetNativeWindow()); 806 } 807 808 virtual void ShowOtherCellular() OVERRIDE { 809 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); 810 } 811 812 virtual bool GetBluetoothAvailable() OVERRIDE { 813 return bluetooth_adapter_->IsPresent(); 814 } 815 816 virtual bool GetBluetoothEnabled() OVERRIDE { 817 return bluetooth_adapter_->IsPowered(); 818 } 819 820 virtual bool GetCellularCarrierInfo(std::string* carrier_id, 821 std::string* topup_url, 822 std::string* setup_url) OVERRIDE { 823 bool result = false; 824 NetworkLibrary* crosnet = NetworkLibrary::Get(); 825 const NetworkDevice* cellular = crosnet->FindCellularDevice(); 826 if (!cellular) 827 return false; 828 829 MobileConfig* config = MobileConfig::GetInstance(); 830 if (config->IsReady()) { 831 *carrier_id = crosnet->GetCellularHomeCarrierId(); 832 const MobileConfig::Carrier* carrier = config->GetCarrier(*carrier_id); 833 if (carrier) { 834 *topup_url = carrier->top_up_url(); 835 result = true; 836 } 837 const MobileConfig::LocaleConfig* locale_config = 838 config->GetLocaleConfig(); 839 if (locale_config) { 840 // Only link to setup URL if SIM card is not inserted. 841 if (cellular->is_sim_absent()) { 842 *setup_url = locale_config->setup_url(); 843 result = true; 844 } 845 } 846 } 847 return result; 848 } 849 850 virtual void ShowCellularURL(const std::string& url) OVERRIDE { 851 chrome::ShowSingletonTab(GetAppropriateBrowser(), GURL(url)); 852 } 853 854 virtual void ChangeProxySettings() OVERRIDE { 855 CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE); 856 LoginDisplayHostImpl::default_host()->OpenProxySettings(); 857 } 858 859 virtual ash::VolumeControlDelegate* 860 GetVolumeControlDelegate() const OVERRIDE { 861 return volume_control_delegate_.get(); 862 } 863 864 virtual void SetVolumeControlDelegate( 865 scoped_ptr<ash::VolumeControlDelegate> delegate) OVERRIDE { 866 volume_control_delegate_.swap(delegate); 867 } 868 869 virtual bool GetSessionStartTime( 870 base::TimeTicks* session_start_time) OVERRIDE { 871 *session_start_time = session_start_time_; 872 return have_session_start_time_; 873 } 874 875 virtual bool GetSessionLengthLimit( 876 base::TimeDelta* session_length_limit) OVERRIDE { 877 *session_length_limit = session_length_limit_; 878 return have_session_length_limit_; 879 } 880 881 virtual int GetSystemTrayMenuWidth() OVERRIDE { 882 return l10n_util::GetLocalizedContentsWidthInPixels( 883 IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS); 884 } 885 886 virtual string16 FormatTimeDuration( 887 const base::TimeDelta& delta) const OVERRIDE { 888 return ui::TimeFormat::TimeDurationLong(delta); 889 } 890 891 virtual void MaybeSpeak(const std::string& utterance) const OVERRIDE { 892 AccessibilityManager::Get()->MaybeSpeak(utterance); 893 } 894 895 private: 896 ash::SystemTray* GetPrimarySystemTray() { 897 return ash::Shell::GetInstance()->GetPrimarySystemTray(); 898 } 899 900 ash::SystemTrayNotifier* GetSystemTrayNotifier() { 901 return ash::Shell::GetInstance()->system_tray_notifier(); 902 } 903 904 // Returns the last active browser. If there is no such browser, creates a new 905 // browser window with an empty tab and returns it. 906 Browser* GetAppropriateBrowser() { 907 return chrome::FindOrCreateTabbedBrowser( 908 ProfileManager::GetDefaultProfileOrOffTheRecord(), 909 chrome::HOST_DESKTOP_TYPE_ASH); 910 } 911 912 void SetProfile(Profile* profile) { 913 // Stop observing the current |user_profile_| on Drive integration status. 914 UnobserveDriveUpdates(); 915 916 user_profile_ = profile; 917 918 // Restart observation, now for the newly set |profile|. 919 ObserveDriveUpdates(); 920 921 PrefService* prefs = profile->GetPrefs(); 922 user_pref_registrar_.reset(new PrefChangeRegistrar); 923 user_pref_registrar_->Init(prefs); 924 user_pref_registrar_->Add( 925 prefs::kUse24HourClock, 926 base::Bind(&SystemTrayDelegate::UpdateClockType, 927 base::Unretained(this))); 928 user_pref_registrar_->Add( 929 prefs::kLanguageRemapSearchKeyTo, 930 base::Bind(&SystemTrayDelegate::OnLanguageRemapSearchKeyToChanged, 931 base::Unretained(this))); 932 user_pref_registrar_->Add( 933 prefs::kShowLogoutButtonInTray, 934 base::Bind(&SystemTrayDelegate::UpdateShowLogoutButtonInTray, 935 base::Unretained(this))); 936 user_pref_registrar_->Add( 937 prefs::kLargeCursorEnabled, 938 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged, 939 base::Unretained(this), 940 ash::A11Y_NOTIFICATION_NONE)); 941 user_pref_registrar_->Add( 942 prefs::kShouldAlwaysShowAccessibilityMenu, 943 base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged, 944 base::Unretained(this), 945 ash::A11Y_NOTIFICATION_NONE)); 946 user_pref_registrar_->Add( 947 prefs::kPerformanceTracingEnabled, 948 base::Bind(&SystemTrayDelegate::UpdatePerformanceTracing, 949 base::Unretained(this))); 950 951 UpdateClockType(); 952 UpdateShowLogoutButtonInTray(); 953 UpdatePerformanceTracing(); 954 search_key_mapped_to_ = 955 profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo); 956 } 957 958 bool UnsetProfile(Profile* profile) { 959 if (profile != user_profile_) 960 return false; 961 user_pref_registrar_.reset(); 962 return true; 963 } 964 965 void ObserveDriveUpdates() { 966 DriveIntegrationService* integration_service = 967 FindDriveIntegrationService(); 968 if (integration_service) 969 integration_service->job_list()->AddObserver(this); 970 } 971 972 void UnobserveDriveUpdates() { 973 DriveIntegrationService* integration_service = 974 FindDriveIntegrationService(); 975 if (integration_service) 976 integration_service->job_list()->RemoveObserver(this); 977 } 978 979 bool ShouldUse24HourClock() const { 980 // On login screen and in guest mode owner default is used for 981 // kUse24HourClock preference. 982 // All other modes default to the default locale value. 983 const ash::user::LoginStatus status = GetUserLoginStatus(); 984 const CrosSettings* const cros_settings = CrosSettings::Get(); 985 bool system_use_24_hour_clock = true; 986 const bool system_value_found = cros_settings->GetBoolean( 987 kSystemUse24HourClock, &system_use_24_hour_clock); 988 989 if (status == ash::user::LOGGED_IN_NONE) 990 return (system_value_found 991 ? system_use_24_hour_clock 992 : (base::GetHourClockType() == base::k24HourClock)); 993 994 const PrefService::Preference* user_pref = 995 user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock); 996 if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue()) 997 return (system_value_found 998 ? system_use_24_hour_clock 999 : (base::GetHourClockType() == base::k24HourClock)); 1000 1001 bool use_24_hour_clock = true; 1002 user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock); 1003 return use_24_hour_clock; 1004 } 1005 1006 void UpdateClockType() { 1007 if (!user_pref_registrar_) 1008 return; 1009 1010 const bool use_24_hour_clock = ShouldUse24HourClock(); 1011 clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock; 1012 GetSystemTrayNotifier()->NotifyDateFormatChanged(); 1013 // This also works for enterprise-managed devices because they never have 1014 // local owner. 1015 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) 1016 CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock); 1017 } 1018 1019 void UpdateShowLogoutButtonInTray() { 1020 GetSystemTrayNotifier()->NotifyShowLoginButtonChanged( 1021 user_pref_registrar_->prefs()->GetBoolean( 1022 prefs::kShowLogoutButtonInTray)); 1023 } 1024 1025 void UpdateSessionStartTime() { 1026 const PrefService* local_state = local_state_registrar_->prefs(); 1027 if (local_state->HasPrefPath(prefs::kSessionStartTime)) { 1028 have_session_start_time_ = true; 1029 session_start_time_ = base::TimeTicks::FromInternalValue( 1030 local_state->GetInt64(prefs::kSessionStartTime)); 1031 } else { 1032 have_session_start_time_ = false; 1033 session_start_time_ = base::TimeTicks(); 1034 } 1035 GetSystemTrayNotifier()->NotifySessionStartTimeChanged(); 1036 } 1037 1038 void UpdateSessionLengthLimit() { 1039 const PrefService* local_state = local_state_registrar_->prefs(); 1040 if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) { 1041 have_session_length_limit_ = true; 1042 session_length_limit_ = base::TimeDelta::FromMilliseconds( 1043 std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit), 1044 kSessionLengthLimitMinMs), 1045 kSessionLengthLimitMaxMs)); 1046 } else { 1047 have_session_length_limit_ = false; 1048 session_length_limit_ = base::TimeDelta(); 1049 } 1050 GetSystemTrayNotifier()->NotifySessionLengthLimitChanged(); 1051 } 1052 1053 // LoginState::Observer overrides. 1054 virtual void LoggedInStateChanged( 1055 chromeos::LoginState::LoggedInState state) OVERRIDE { 1056 UpdateClockType(); 1057 } 1058 1059 // Overridden from PowerManagerClient::Observer. 1060 virtual void BrightnessChanged(int level, bool user_initiated) OVERRIDE { 1061 double leveld = static_cast<double>(level); 1062 GetSystemTrayNotifier()->NotifyBrightnessChanged(leveld, user_initiated); 1063 } 1064 1065 // Overridden from PowerManagerClient::Observer: 1066 virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE { 1067 GetSystemTrayNotifier()->NotifyRefreshClock(); 1068 } 1069 1070 // Overridden from SessionManagerClient::Observer. 1071 virtual void LockScreen() OVERRIDE { 1072 screen_locked_ = true; 1073 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( 1074 GetUserLoginStatus()); 1075 } 1076 1077 virtual void UnlockScreen() OVERRIDE { 1078 screen_locked_ = false; 1079 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( 1080 GetUserLoginStatus()); 1081 } 1082 1083 // TODO(sad): Override more from PowerManagerClient::Observer here. 1084 1085 gfx::NativeWindow GetNativeWindow() const { 1086 return GetNativeWindowByStatus(GetUserLoginStatus()); 1087 } 1088 1089 // Overridden from NetworkLibrary::NetworkManagerObserver. 1090 virtual void OnNetworkManagerChanged(NetworkLibrary* crosnet) OVERRIDE { 1091 // TODO(stevenjb): Migrate to NetworkStateHandler. 1092 data_promo_notification_->ShowOptionalMobileDataPromoNotification( 1093 crosnet, GetPrimarySystemTray(), this); 1094 UpdateCellular(); 1095 } 1096 1097 // content::NotificationObserver implementation. 1098 virtual void Observe(int type, 1099 const content::NotificationSource& source, 1100 const content::NotificationDetails& details) OVERRIDE { 1101 switch (type) { 1102 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { 1103 UpgradeDetector* detector = 1104 content::Source<UpgradeDetector>(source).ptr(); 1105 ash::UpdateObserver::UpdateSeverity severity = 1106 ash::UpdateObserver::UPDATE_NORMAL; 1107 switch (detector->upgrade_notification_stage()) { 1108 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: 1109 severity = ash::UpdateObserver::UPDATE_SEVERE_RED; 1110 break; 1111 1112 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: 1113 severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE; 1114 break; 1115 1116 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: 1117 severity = ash::UpdateObserver::UPDATE_LOW_GREEN; 1118 break; 1119 1120 case UpgradeDetector::UPGRADE_ANNOYANCE_LOW: 1121 default: 1122 severity = ash::UpdateObserver::UPDATE_NORMAL; 1123 break; 1124 } 1125 GetSystemTrayNotifier()->NotifyUpdateRecommended(severity); 1126 break; 1127 } 1128 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: { 1129 // This notification is also sent on login screen when user avatar 1130 // is loaded from file. 1131 if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) { 1132 GetSystemTrayNotifier()->NotifyUserUpdate(); 1133 } 1134 break; 1135 } 1136 case chrome::NOTIFICATION_PROFILE_CREATED: { 1137 SetProfile(content::Source<Profile>(source).ptr()); 1138 registrar_->Remove(this, 1139 chrome::NOTIFICATION_PROFILE_CREATED, 1140 content::NotificationService::AllSources()); 1141 break; 1142 } 1143 case chrome::NOTIFICATION_PROFILE_DESTROYED: { 1144 if (UnsetProfile(content::Source<Profile>(source).ptr())) { 1145 registrar_->Remove(this, 1146 chrome::NOTIFICATION_PROFILE_DESTROYED, 1147 content::NotificationService::AllSources()); 1148 } 1149 break; 1150 } 1151 case chrome::NOTIFICATION_SESSION_STARTED: { 1152 ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( 1153 GetUserLoginStatus()); 1154 SetProfile(ProfileManager::GetDefaultProfile()); 1155 break; 1156 } 1157 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK: 1158 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE: 1159 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: { 1160 AccessibilityStatusEventDetails* accessibility_status = 1161 content::Details<AccessibilityStatusEventDetails>(details).ptr(); 1162 OnAccessibilityModeChanged(accessibility_status->notify); 1163 break; 1164 } 1165 default: 1166 NOTREACHED(); 1167 } 1168 } 1169 1170 void OnLanguageRemapSearchKeyToChanged() { 1171 search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger( 1172 prefs::kLanguageRemapSearchKeyTo); 1173 } 1174 1175 void OnAccessibilityModeChanged( 1176 ash::AccessibilityNotificationVisibility notify) { 1177 GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify); 1178 } 1179 1180 void UpdatePerformanceTracing() { 1181 if (!user_pref_registrar_) 1182 return; 1183 bool value = 1184 user_pref_registrar_->prefs()->GetBoolean( 1185 prefs::kPerformanceTracingEnabled); 1186 GetSystemTrayNotifier()->NotifyTracingModeChanged(value); 1187 } 1188 1189 // Overridden from InputMethodManager::Observer. 1190 virtual void InputMethodChanged( 1191 input_method::InputMethodManager* manager, bool show_message) OVERRIDE { 1192 GetSystemTrayNotifier()->NotifyRefreshIME(show_message); 1193 } 1194 1195 virtual void InputMethodPropertyChanged( 1196 input_method::InputMethodManager* manager) OVERRIDE { 1197 GetSystemTrayNotifier()->NotifyRefreshIME(false); 1198 } 1199 1200 // drive::JobListObserver overrides. 1201 virtual void OnJobAdded(const drive::JobInfo& job_info) OVERRIDE { 1202 OnJobUpdated(job_info); 1203 } 1204 1205 virtual void OnJobDone(const drive::JobInfo& job_info, 1206 drive::FileError error) OVERRIDE { 1207 ash::DriveOperationStatus status; 1208 if (ConvertToFinishedDriveOperationStatus(job_info, error, &status)) 1209 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); 1210 } 1211 1212 virtual void OnJobUpdated(const drive::JobInfo& job_info) OVERRIDE { 1213 ash::DriveOperationStatus status; 1214 if (ConvertToDriveOperationStatus(job_info, &status)) 1215 GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); 1216 } 1217 1218 DriveIntegrationService* FindDriveIntegrationService() { 1219 return user_profile_ ? 1220 DriveIntegrationServiceFactory::FindForProfile(user_profile_) : NULL; 1221 } 1222 1223 // Overridden from system::TimezoneSettings::Observer. 1224 virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE { 1225 GetSystemTrayNotifier()->NotifyRefreshClock(); 1226 } 1227 1228 // Overridden from SystemClockClient::Observer. 1229 virtual void SystemClockUpdated() OVERRIDE { 1230 GetSystemTrayNotifier()->NotifySystemClockTimeUpdated(); 1231 } 1232 1233 // Overridden from BluetoothAdapter::Observer. 1234 virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, 1235 bool present) OVERRIDE { 1236 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1237 } 1238 1239 virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, 1240 bool powered) OVERRIDE { 1241 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1242 } 1243 1244 virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, 1245 bool discovering) OVERRIDE { 1246 GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged(); 1247 } 1248 1249 virtual void DeviceAdded(device::BluetoothAdapter* adapter, 1250 device::BluetoothDevice* device) OVERRIDE { 1251 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1252 } 1253 1254 virtual void DeviceChanged(device::BluetoothAdapter* adapter, 1255 device::BluetoothDevice* device) OVERRIDE { 1256 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1257 } 1258 1259 virtual void DeviceRemoved(device::BluetoothAdapter* adapter, 1260 device::BluetoothDevice* device) OVERRIDE { 1261 GetSystemTrayNotifier()->NotifyRefreshBluetooth(); 1262 } 1263 1264 // Overridden from SystemKeyEventListener::CapsLockObserver. 1265 virtual void OnCapsLockChange(bool enabled) OVERRIDE { 1266 bool search_mapped_to_caps_lock = false; 1267 if (!base::chromeos::IsRunningOnChromeOS() || 1268 search_key_mapped_to_ == input_method::kCapsLockKey) 1269 search_mapped_to_caps_lock = true; 1270 GetSystemTrayNotifier()->NotifyCapsLockChanged( 1271 enabled, search_mapped_to_caps_lock); 1272 } 1273 1274 // Overridden from ash::NetworkTrayDelegate 1275 virtual void NotificationLinkClicked( 1276 ash::NetworkObserver::MessageType message_type, 1277 size_t link_index) OVERRIDE { 1278 if (message_type == ash::NetworkObserver::ERROR_OUT_OF_CREDITS) { 1279 const NetworkState* cellular = 1280 NetworkHandler::Get()->network_state_handler()-> 1281 FirstNetworkByType(flimflam::kTypeCellular); 1282 std::string service_path = cellular ? cellular->path() : ""; 1283 ShowNetworkSettings(service_path); 1284 1285 ash::Shell::GetInstance()->system_tray_notifier()-> 1286 NotifyClearNetworkMessage(message_type); 1287 } 1288 if (message_type != ash::NetworkObserver::MESSAGE_DATA_PROMO) 1289 return; 1290 // If we have deal info URL defined that means that there're 1291 // 2 links in bubble. Let the user close it manually then thus giving 1292 // ability to navigate to second link. 1293 // mobile_data_bubble_ will be set to NULL in BubbleClosing callback. 1294 std::string deal_info_url = data_promo_notification_->deal_info_url(); 1295 std::string deal_topup_url = data_promo_notification_->deal_topup_url(); 1296 if (deal_info_url.empty()) 1297 data_promo_notification_->CloseNotification(); 1298 1299 std::string deal_url_to_open; 1300 if (link_index == 0) { 1301 if (!deal_topup_url.empty()) { 1302 deal_url_to_open = deal_topup_url; 1303 } else { 1304 const Network* cellular = 1305 NetworkLibrary::Get()->cellular_network(); 1306 if (!cellular) 1307 return; 1308 ShowNetworkSettings(cellular->service_path()); 1309 return; 1310 } 1311 } else if (link_index == 1) { 1312 deal_url_to_open = deal_info_url; 1313 } 1314 1315 if (!deal_url_to_open.empty()) { 1316 Browser* browser = GetAppropriateBrowser(); 1317 if (!browser) 1318 return; 1319 chrome::ShowSingletonTab(browser, GURL(deal_url_to_open)); 1320 } 1321 } 1322 1323 virtual void UpdateEnterpriseDomain() { 1324 std::string enterprise_domain = 1325 g_browser_process->browser_policy_connector()->GetEnterpriseDomain(); 1326 if (enterprise_domain_ != enterprise_domain) { 1327 enterprise_domain_ = enterprise_domain; 1328 GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged(); 1329 } 1330 } 1331 1332 // Overridden from CloudPolicyStore::Observer 1333 virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE { 1334 UpdateEnterpriseDomain(); 1335 } 1336 1337 virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE { 1338 UpdateEnterpriseDomain(); 1339 } 1340 1341 // Overridden from ash::SessionStateObserver 1342 virtual void ActiveUserChanged(const std::string& user_id) OVERRIDE { 1343 GetSystemTrayNotifier()->NotifyUserUpdate(); 1344 } 1345 1346 void UpdateCellular() { 1347 const CellularNetworkVector& cellular_networks = 1348 NetworkLibrary::Get()->cellular_networks(); 1349 if (cellular_networks.empty()) 1350 return; 1351 // We only care about the first cellular network (in practice there will 1352 // only ever be one) 1353 const CellularNetwork* cellular = cellular_networks[0]; 1354 if (cellular->activation_state() == ACTIVATION_STATE_ACTIVATING) { 1355 cellular_activating_ = true; 1356 } else if (cellular->activated() && cellular_activating_) { 1357 cellular_activating_ = false; 1358 ash::NetworkObserver::NetworkType type = NetworkTypeForCellular(cellular); 1359 ash::Shell::GetInstance()->system_tray_notifier()-> 1360 NotifySetNetworkMessage( 1361 NULL, 1362 ash::NetworkObserver::MESSAGE_DATA_PROMO, 1363 type, 1364 l10n_util::GetStringUTF16(IDS_NETWORK_CELLULAR_ACTIVATED_TITLE), 1365 l10n_util::GetStringFUTF16(IDS_NETWORK_CELLULAR_ACTIVATED, 1366 UTF8ToUTF16((cellular->name()))), 1367 std::vector<string16>()); 1368 } 1369 } 1370 1371 scoped_ptr<base::WeakPtrFactory<SystemTrayDelegate> > ui_weak_ptr_factory_; 1372 scoped_ptr<content::NotificationRegistrar> registrar_; 1373 scoped_ptr<PrefChangeRegistrar> local_state_registrar_; 1374 scoped_ptr<PrefChangeRegistrar> user_pref_registrar_; 1375 Profile* user_profile_; 1376 std::string active_network_path_; 1377 base::HourClockType clock_type_; 1378 int search_key_mapped_to_; 1379 bool screen_locked_; 1380 bool have_session_start_time_; 1381 base::TimeTicks session_start_time_; 1382 bool have_session_length_limit_; 1383 base::TimeDelta session_length_limit_; 1384 std::string enterprise_domain_; 1385 1386 scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; 1387 1388 scoped_ptr<DataPromoNotification> data_promo_notification_; 1389 bool cellular_activating_; 1390 bool cellular_out_of_credits_; 1391 1392 scoped_ptr<ash::VolumeControlDelegate> volume_control_delegate_; 1393 1394 DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegate); 1395 }; 1396 1397 } // namespace 1398 1399 ash::SystemTrayDelegate* CreateSystemTrayDelegate() { 1400 return new chromeos::SystemTrayDelegate(); 1401 } 1402 1403 } // namespace chromeos 1404