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