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 |