1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/ash/chrome_shell_delegate.h" 6 7#include "ash/accelerators/magnifier_key_scroller.h" 8#include "ash/accelerators/spoken_feedback_toggler.h" 9#include "ash/accessibility_delegate.h" 10#include "ash/wm/mru_window_tracker.h" 11#include "ash/wm/window_util.h" 12#include "base/command_line.h" 13#include "base/prefs/pref_service.h" 14#include "chrome/browser/accessibility/accessibility_events.h" 15#include "chrome/browser/app_mode/app_mode_utils.h" 16#include "chrome/browser/chrome_notification_types.h" 17#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 18#include "chrome/browser/chromeos/accessibility/magnification_manager.h" 19#include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h" 20#include "chrome/browser/chromeos/display/display_configuration_observer.h" 21#include "chrome/browser/chromeos/display/display_preferences.h" 22#include "chrome/browser/chromeos/profiles/profile_helper.h" 23#include "chrome/browser/profiles/profile.h" 24#include "chrome/browser/profiles/profile_manager.h" 25#include "chrome/browser/signin/signin_error_notifier_factory_ash.h" 26#include "chrome/browser/speech/tts_controller.h" 27#include "chrome/browser/sync/sync_error_notifier_factory_ash.h" 28#include "chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.h" 29#include "chrome/browser/ui/ash/media_delegate_chromeos.h" 30#include "chrome/browser/ui/ash/session_state_delegate_chromeos.h" 31#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h" 32#include "chrome/browser/ui/browser.h" 33#include "chrome/browser/ui/browser_finder.h" 34#include "chrome/browser/ui/browser_window.h" 35#include "chrome/common/pref_names.h" 36#include "chrome/grit/generated_resources.h" 37#include "chromeos/chromeos_switches.h" 38#include "chromeos/ime/input_method_manager.h" 39#include "content/public/browser/notification_service.h" 40#include "content/public/browser/user_metrics.h" 41#include "ui/aura/window.h" 42#include "ui/base/l10n/l10n_util.h" 43 44namespace { 45 46void InitAfterSessionStart() { 47 // Restore focus after the user session is started. It's needed because some 48 // windows can be opened in background while login UI is still active because 49 // we currently restore browser windows before login UI is deleted. 50 ash::Shell* shell = ash::Shell::GetInstance(); 51 ash::MruWindowTracker::WindowList mru_list = 52 shell->mru_window_tracker()->BuildMruWindowList(); 53 if (!mru_list.empty()) 54 mru_list.front()->Focus(); 55 56#if defined(USE_X11) 57 // Enable magnifier scroll keys as there may be no mouse cursor in kiosk mode. 58 ash::MagnifierKeyScroller::SetEnabled(chrome::IsRunningInForcedAppMode()); 59 60 // Enable long press action to toggle spoken feedback with hotrod 61 // remote which can't handle shortcut. 62 ash::SpokenFeedbackToggler::SetEnabled(chrome::IsRunningInForcedAppMode()); 63#endif 64} 65 66class AccessibilityDelegateImpl : public ash::AccessibilityDelegate { 67 public: 68 AccessibilityDelegateImpl() {} 69 virtual ~AccessibilityDelegateImpl() {} 70 71 virtual void ToggleHighContrast() OVERRIDE { 72 DCHECK(chromeos::AccessibilityManager::Get()); 73 chromeos::AccessibilityManager::Get()->EnableHighContrast( 74 !chromeos::AccessibilityManager::Get()->IsHighContrastEnabled()); 75 } 76 77 virtual bool IsSpokenFeedbackEnabled() const OVERRIDE { 78 DCHECK(chromeos::AccessibilityManager::Get()); 79 return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled(); 80 } 81 82 virtual void ToggleSpokenFeedback( 83 ash::AccessibilityNotificationVisibility notify) OVERRIDE { 84 DCHECK(chromeos::AccessibilityManager::Get()); 85 chromeos::AccessibilityManager::Get()->ToggleSpokenFeedback(notify); 86 } 87 88 virtual bool IsHighContrastEnabled() const OVERRIDE { 89 DCHECK(chromeos::AccessibilityManager::Get()); 90 return chromeos::AccessibilityManager::Get()->IsHighContrastEnabled(); 91 } 92 93 virtual void SetMagnifierEnabled(bool enabled) OVERRIDE { 94 DCHECK(chromeos::MagnificationManager::Get()); 95 return chromeos::MagnificationManager::Get()->SetMagnifierEnabled(enabled); 96 } 97 98 virtual void SetMagnifierType(ash::MagnifierType type) OVERRIDE { 99 DCHECK(chromeos::MagnificationManager::Get()); 100 return chromeos::MagnificationManager::Get()->SetMagnifierType(type); 101 } 102 103 virtual bool IsMagnifierEnabled() const OVERRIDE { 104 DCHECK(chromeos::MagnificationManager::Get()); 105 return chromeos::MagnificationManager::Get()->IsMagnifierEnabled(); 106 } 107 108 virtual ash::MagnifierType GetMagnifierType() const OVERRIDE { 109 DCHECK(chromeos::MagnificationManager::Get()); 110 return chromeos::MagnificationManager::Get()->GetMagnifierType(); 111 } 112 113 virtual void SetLargeCursorEnabled(bool enabled) OVERRIDE { 114 DCHECK(chromeos::AccessibilityManager::Get()); 115 return chromeos::AccessibilityManager::Get()->EnableLargeCursor(enabled); 116 } 117 118 virtual bool IsLargeCursorEnabled() const OVERRIDE { 119 DCHECK(chromeos::AccessibilityManager::Get()); 120 return chromeos::AccessibilityManager::Get()->IsLargeCursorEnabled(); 121 } 122 123 virtual void SetAutoclickEnabled(bool enabled) OVERRIDE { 124 DCHECK(chromeos::AccessibilityManager::Get()); 125 return chromeos::AccessibilityManager::Get()->EnableAutoclick(enabled); 126 } 127 128 virtual bool IsAutoclickEnabled() const OVERRIDE { 129 DCHECK(chromeos::AccessibilityManager::Get()); 130 return chromeos::AccessibilityManager::Get()->IsAutoclickEnabled(); 131 } 132 133 virtual void SetVirtualKeyboardEnabled(bool enabled) OVERRIDE { 134 DCHECK(chromeos::AccessibilityManager::Get()); 135 return chromeos::AccessibilityManager::Get()-> 136 EnableVirtualKeyboard(enabled); 137 } 138 139 virtual bool IsVirtualKeyboardEnabled() const OVERRIDE { 140 DCHECK(chromeos::AccessibilityManager::Get()); 141 return chromeos::AccessibilityManager::Get()->IsVirtualKeyboardEnabled(); 142 } 143 144 virtual bool ShouldShowAccessibilityMenu() const OVERRIDE { 145 DCHECK(chromeos::AccessibilityManager::Get()); 146 return chromeos::AccessibilityManager::Get()-> 147 ShouldShowAccessibilityMenu(); 148 } 149 150 virtual bool IsBrailleDisplayConnected() const OVERRIDE { 151 DCHECK(chromeos::AccessibilityManager::Get()); 152 return chromeos::AccessibilityManager::Get()->IsBrailleDisplayConnected(); 153 } 154 155 virtual void SilenceSpokenFeedback() const OVERRIDE { 156 TtsController::GetInstance()->Stop(); 157 } 158 159 virtual void SaveScreenMagnifierScale(double scale) OVERRIDE { 160 if (chromeos::MagnificationManager::Get()) 161 chromeos::MagnificationManager::Get()->SaveScreenMagnifierScale(scale); 162 } 163 164 virtual double GetSavedScreenMagnifierScale() OVERRIDE { 165 if (chromeos::MagnificationManager::Get()) { 166 return chromeos::MagnificationManager::Get()-> 167 GetSavedScreenMagnifierScale(); 168 } 169 return std::numeric_limits<double>::min(); 170 } 171 172 virtual void TriggerAccessibilityAlert( 173 ash::AccessibilityAlert alert) OVERRIDE { 174 Profile* profile = ProfileManager::GetActiveUserProfile(); 175 if (profile) { 176 switch (alert) { 177 case ash::A11Y_ALERT_WINDOW_NEEDED: { 178 AccessibilityAlertInfo event( 179 profile, l10n_util::GetStringUTF8(IDS_A11Y_ALERT_WINDOW_NEEDED)); 180 SendControlAccessibilityNotification( 181 ui::AX_EVENT_ALERT, &event); 182 break; 183 } 184 case ash::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED: { 185 AccessibilityAlertInfo event( 186 profile, l10n_util::GetStringUTF8( 187 IDS_A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED)); 188 SendControlAccessibilityNotification( 189 ui::AX_EVENT_ALERT, &event); 190 break; 191 } 192 case ash::A11Y_ALERT_NONE: 193 break; 194 } 195 } 196 } 197 198 virtual ash::AccessibilityAlert GetLastAccessibilityAlert() OVERRIDE { 199 return ash::A11Y_ALERT_NONE; 200 } 201 202 virtual void PlayEarcon(int sound_key) OVERRIDE { 203 DCHECK(chromeos::AccessibilityManager::Get()); 204 return chromeos::AccessibilityManager::Get()->PlayEarcon(sound_key); 205 } 206 207 virtual base::TimeDelta PlayShutdownSound() const OVERRIDE { 208 return chromeos::AccessibilityManager::Get()->PlayShutdownSound(); 209 } 210 211 private: 212 DISALLOW_COPY_AND_ASSIGN(AccessibilityDelegateImpl); 213}; 214 215} // anonymous namespace 216 217bool ChromeShellDelegate::IsFirstRunAfterBoot() const { 218 return CommandLine::ForCurrentProcess()->HasSwitch( 219 chromeos::switches::kFirstExecAfterBoot); 220} 221 222void ChromeShellDelegate::PreInit() { 223 chromeos::LoadDisplayPreferences(IsFirstRunAfterBoot()); 224 // Set the observer now so that we can save the initial state 225 // in Shell::Init. 226 display_configuration_observer_.reset( 227 new chromeos::DisplayConfigurationObserver()); 228} 229 230void ChromeShellDelegate::PreShutdown() { 231 display_configuration_observer_.reset(); 232} 233 234ash::SessionStateDelegate* ChromeShellDelegate::CreateSessionStateDelegate() { 235 return new SessionStateDelegateChromeos; 236} 237 238ash::AccessibilityDelegate* ChromeShellDelegate::CreateAccessibilityDelegate() { 239 return new AccessibilityDelegateImpl; 240} 241 242ash::NewWindowDelegate* ChromeShellDelegate::CreateNewWindowDelegate() { 243 return new ChromeNewWindowDelegateChromeos; 244} 245 246ash::MediaDelegate* ChromeShellDelegate::CreateMediaDelegate() { 247 return new MediaDelegateChromeOS; 248} 249 250ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate() { 251 return chromeos::CreateSystemTrayDelegate(); 252} 253 254ash::UserWallpaperDelegate* ChromeShellDelegate::CreateUserWallpaperDelegate() { 255 return chromeos::CreateUserWallpaperDelegate(); 256} 257 258void ChromeShellDelegate::Observe(int type, 259 const content::NotificationSource& source, 260 const content::NotificationDetails& details) { 261 switch (type) { 262 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: { 263 Profile* profile = content::Details<Profile>(details).ptr(); 264 if (!chromeos::ProfileHelper::IsSigninProfile(profile) && 265 !profile->IsGuestSession() && !profile->IsSupervised()) { 266 // Start the error notifier services to show auth/sync notifications. 267 SigninErrorNotifierFactory::GetForProfile(profile); 268 SyncErrorNotifierFactory::GetForProfile(profile); 269 } 270 ash::Shell::GetInstance()->OnLoginUserProfilePrepared(); 271 break; 272 } 273 case chrome::NOTIFICATION_SESSION_STARTED: 274 InitAfterSessionStart(); 275 ash::Shell::GetInstance()->ShowShelf(); 276 break; 277 default: 278 NOTREACHED() << "Unexpected notification " << type; 279 } 280} 281 282void ChromeShellDelegate::PlatformInit() { 283 registrar_.Add(this, 284 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 285 content::NotificationService::AllSources()); 286 registrar_.Add(this, 287 chrome::NOTIFICATION_SESSION_STARTED, 288 content::NotificationService::AllSources()); 289} 290