blob: 0c37d2a6f31bd1d2167954d27c71978a3ee21d3d [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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
Ben Murdochba5b9a62013-08-12 14:20:17 +01007#include "apps/shell_window_registry.h"
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +01008#include "apps/ui/native_app_window.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "ash/keyboard_overlay/keyboard_overlay_view.h"
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +010010#include "ash/wm/mru_window_tracker.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000011#include "ash/wm/window_util.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "base/command_line.h"
13#include "base/prefs/pref_service.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010014#include "chrome/browser/chrome_notification_types.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010015#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000016#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
17#include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000018#include "chrome/browser/chromeos/display/display_preferences.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000019#include "chrome/browser/chromeos/extensions/media_player_api.h"
20#include "chrome/browser/chromeos/extensions/media_player_event_router.h"
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010021#include "chrome/browser/chromeos/file_manager/app_id.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000022#include "chrome/browser/chromeos/system/ash_system_tray_delegate.h"
23#include "chrome/browser/extensions/api/terminal/terminal_extension_helper.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010024#include "chrome/browser/extensions/extension_service.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000025#include "chrome/browser/profiles/profile_manager.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010026#include "chrome/browser/speech/tts_controller.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000027#include "chrome/browser/ui/ash/caps_lock_delegate_chromeos.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010028#include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000029#include "chrome/browser/ui/browser.h"
30#include "chrome/browser/ui/browser_finder.h"
31#include "chrome/browser/ui/browser_window.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010032#include "chrome/browser/ui/extensions/application_launch.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000033#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000034#include "chrome/common/pref_names.h"
35#include "chrome/common/url_constants.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010036#include "chromeos/chromeos_switches.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000037#include "chromeos/dbus/dbus_thread_manager.h"
38#include "chromeos/dbus/power_manager_client.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010039#include "chromeos/ime/input_method_manager.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010040#include "content/public/browser/notification_service.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000041#include "content/public/browser/user_metrics.h"
42#include "content/public/browser/web_contents.h"
43#include "content/public/browser/web_contents_view.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000044
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +010045namespace {
46
47// This function is used for restoring focus after the user session is started.
48// It's needed because some windows can be opened in background while login UI
49// is still active because we currently restore browser windows before login UI
50// is deleted.
51void RestoreFocus() {
52 ash::MruWindowTracker::WindowList mru_list =
53 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
54 if (!mru_list.empty())
55 mru_list.front()->Focus();
56}
57
58} // anonymous namespace
59
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000060bool ChromeShellDelegate::IsFirstRunAfterBoot() const {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010061 return CommandLine::ForCurrentProcess()->HasSwitch(
Ben Murdochba5b9a62013-08-12 14:20:17 +010062 chromeos::switches::kFirstExecAfterBoot);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000063}
64
65void ChromeShellDelegate::PreInit() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010066 chromeos::LoadDisplayPreferences(IsFirstRunAfterBoot());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000067}
68
69void ChromeShellDelegate::Shutdown() {
70 content::RecordAction(content::UserMetricsAction("Shutdown"));
71 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
72 RequestShutdown();
73}
74
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +010075void ChromeShellDelegate::OpenFileManager() {
76 using file_manager::kFileManagerAppId;
77 Profile* const profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
78 const apps::ShellWindowRegistry* const registry =
79 apps::ShellWindowRegistry::Get(profile);
80 const apps::ShellWindowRegistry::ShellWindowList list =
81 registry->GetShellWindowsForApp(kFileManagerAppId);
82 if (list.empty()) {
83 // Open the new window.
84 const ExtensionService* const service = profile->GetExtensionService();
85 if (service == NULL ||
86 !service->IsExtensionEnabledForLauncher(kFileManagerAppId))
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000087 return;
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +010088 const extensions::Extension* const extension =
89 service->GetInstalledExtension(kFileManagerAppId);
90 // event_flags = 0 means this invokes the same behavior as the launcher
91 // item is clicked without any keyboard modifiers.
92 OpenApplication(AppLaunchParams(profile, extension, 0 /* event_flags */));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000093 } else {
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +010094 // Activate the existing window.
95 list.front()->GetBaseWindow()->Activate();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000096 }
97}
98
99void ChromeShellDelegate::OpenCrosh() {
Torne (Richard Coles)d0247b12013-09-19 22:36:51 +0100100 GURL crosh_url = extensions::TerminalExtensionHelper::GetCroshExtensionURL(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000101 ProfileManager::GetDefaultProfileOrOffTheRecord());
102 if (!crosh_url.is_valid())
103 return;
104 Browser* browser = GetTargetBrowser();
105 content::WebContents* page = browser->OpenURL(
106 content::OpenURLParams(crosh_url,
107 content::Referrer(),
108 NEW_FOREGROUND_TAB,
109 content::PAGE_TRANSITION_GENERATED,
110 false));
111 browser->window()->Show();
112 browser->window()->Activate();
113 page->GetView()->Focus();
114}
115
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000116void ChromeShellDelegate::ToggleHighContrast() {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100117 DCHECK(chromeos::AccessibilityManager::Get());
118 bool enabled = chromeos::AccessibilityManager::Get()->IsHighContrastEnabled();
119 chromeos::AccessibilityManager::Get()->EnableHighContrast(!enabled);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000120}
121
122bool ChromeShellDelegate::IsSpokenFeedbackEnabled() const {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100123 DCHECK(chromeos::AccessibilityManager::Get());
124 return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000125}
126
127void ChromeShellDelegate::ToggleSpokenFeedback(
128 ash::AccessibilityNotificationVisibility notify) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100129 DCHECK(chromeos::AccessibilityManager::Get());
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +0100130 chromeos::AccessibilityManager::Get()->ToggleSpokenFeedback(notify);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000131}
132
133bool ChromeShellDelegate::IsHighContrastEnabled() const {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100134 DCHECK(chromeos::AccessibilityManager::Get());
135 return chromeos::AccessibilityManager::Get()->IsHighContrastEnabled();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000136}
137
138bool ChromeShellDelegate::IsMagnifierEnabled() const {
139 DCHECK(chromeos::MagnificationManager::Get());
140 return chromeos::MagnificationManager::Get()->IsMagnifierEnabled();
141}
142
143ash::MagnifierType ChromeShellDelegate::GetMagnifierType() const {
144 DCHECK(chromeos::MagnificationManager::Get());
145 return chromeos::MagnificationManager::Get()->GetMagnifierType();
146}
147
148void ChromeShellDelegate::SetMagnifierEnabled(bool enabled) {
149 DCHECK(chromeos::MagnificationManager::Get());
150 return chromeos::MagnificationManager::Get()->SetMagnifierEnabled(enabled);
151}
152
153void ChromeShellDelegate::SetMagnifierType(ash::MagnifierType type) {
154 DCHECK(chromeos::MagnificationManager::Get());
155 return chromeos::MagnificationManager::Get()->SetMagnifierType(type);
156}
157
158void ChromeShellDelegate::SaveScreenMagnifierScale(double scale) {
159 if (chromeos::MagnificationManager::Get())
160 chromeos::MagnificationManager::Get()->SaveScreenMagnifierScale(scale);
161}
162
163double ChromeShellDelegate::GetSavedScreenMagnifierScale() {
164 if (chromeos::MagnificationManager::Get()) {
165 return chromeos::MagnificationManager::Get()->
166 GetSavedScreenMagnifierScale();
167 }
168 return std::numeric_limits<double>::min();
169}
170
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100171void ChromeShellDelegate::SetLargeCursorEnabled(bool enabled) {
172 DCHECK(chromeos::AccessibilityManager::Get());
173 return chromeos::AccessibilityManager::Get()->EnableLargeCursor(enabled);
174}
175
176bool ChromeShellDelegate::IsLargeCursorEnabled() const {
177 DCHECK(chromeos::AccessibilityManager::Get());
178 return chromeos::AccessibilityManager::Get()->IsLargeCursorEnabled();
179}
180
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000181ash::CapsLockDelegate* ChromeShellDelegate::CreateCapsLockDelegate() {
182 chromeos::input_method::XKeyboard* xkeyboard =
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100183 chromeos::input_method::InputMethodManager::Get()->GetXKeyboard();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000184 return new CapsLockDelegate(xkeyboard);
185}
186
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100187ash::SessionStateDelegate* ChromeShellDelegate::CreateSessionStateDelegate() {
188 return new SessionStateDelegateChromeos;
189}
190
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000191void ChromeShellDelegate::ShowKeyboardOverlay() {
192 // TODO(mazda): Move the show logic to ash (http://crbug.com/124222).
193 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
194 std::string url(chrome::kChromeUIKeyboardOverlayURL);
195 ash::KeyboardOverlayView::ShowDialog(profile,
196 new ChromeWebContentsHandler,
197 GURL(url));
198}
199
200bool ChromeShellDelegate::ShouldAlwaysShowAccessibilityMenu() const {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000201 Profile* profile = ProfileManager::GetDefaultProfile();
202 if (!profile)
203 return false;
204
205 PrefService* user_pref_service = profile->GetPrefs();
206 return user_pref_service &&
207 user_pref_service->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu);
208}
209
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100210void ChromeShellDelegate::SilenceSpokenFeedback() const {
211 TtsController::GetInstance()->Stop();
212}
213
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000214ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate() {
215 return chromeos::CreateSystemTrayDelegate();
216}
217
218ash::UserWallpaperDelegate* ChromeShellDelegate::CreateUserWallpaperDelegate() {
219 return chromeos::CreateUserWallpaperDelegate();
220}
221
222void ChromeShellDelegate::HandleMediaNextTrack() {
223 extensions::MediaPlayerAPI::Get(
224 ProfileManager::GetDefaultProfileOrOffTheRecord())->
225 media_player_event_router()->NotifyNextTrack();
226}
227
228void ChromeShellDelegate::HandleMediaPlayPause() {
229 extensions::MediaPlayerAPI::Get(
230 ProfileManager::GetDefaultProfileOrOffTheRecord())->
231 media_player_event_router()->NotifyTogglePlayState();
232}
233
234void ChromeShellDelegate::HandleMediaPrevTrack() {
235 extensions::MediaPlayerAPI::Get(
236 ProfileManager::GetDefaultProfileOrOffTheRecord())->
237 media_player_event_router()->NotifyPrevTrack();
238}
239
240void ChromeShellDelegate::Observe(int type,
241 const content::NotificationSource& source,
242 const content::NotificationDetails& details) {
243 switch (type) {
244 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED:
245 ash::Shell::GetInstance()->CreateLauncher();
246 break;
247 case chrome::NOTIFICATION_SESSION_STARTED:
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100248 RestoreFocus();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000249 ash::Shell::GetInstance()->ShowLauncher();
250 break;
251 default:
252 NOTREACHED() << "Unexpected notification " << type;
253 }
254}
255
256void ChromeShellDelegate::PlatformInit() {
257 registrar_.Add(this,
258 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
259 content::NotificationService::AllSources());
260 registrar_.Add(this,
261 chrome::NOTIFICATION_SESSION_STARTED,
262 content::NotificationService::AllSources());
263}