chrome_shell_delegate_chromeos.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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 "apps/native_app_window.h"
8#include "apps/shell_window_registry.h"
9#include "ash/keyboard_overlay/keyboard_overlay_view.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/chrome_notification_types.h"
15#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
16#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
17#include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h"
18#include "chrome/browser/chromeos/display/display_preferences.h"
19#include "chrome/browser/chromeos/extensions/media_player_api.h"
20#include "chrome/browser/chromeos/extensions/media_player_event_router.h"
21#include "chrome/browser/chromeos/file_manager/app_id.h"
22#include "chrome/browser/chromeos/system/ash_system_tray_delegate.h"
23#include "chrome/browser/extensions/api/terminal/terminal_extension_helper.h"
24#include "chrome/browser/extensions/extension_service.h"
25#include "chrome/browser/profiles/profile_manager.h"
26#include "chrome/browser/speech/tts_controller.h"
27#include "chrome/browser/ui/ash/caps_lock_delegate_chromeos.h"
28#include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
29#include "chrome/browser/ui/browser.h"
30#include "chrome/browser/ui/browser_finder.h"
31#include "chrome/browser/ui/browser_window.h"
32#include "chrome/browser/ui/extensions/application_launch.h"
33#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
34#include "chrome/common/pref_names.h"
35#include "chrome/common/url_constants.h"
36#include "chromeos/chromeos_switches.h"
37#include "chromeos/dbus/dbus_thread_manager.h"
38#include "chromeos/dbus/power_manager_client.h"
39#include "chromeos/ime/input_method_manager.h"
40#include "content/public/browser/notification_service.h"
41#include "content/public/browser/user_metrics.h"
42#include "content/public/browser/web_contents.h"
43#include "content/public/browser/web_contents_view.h"
44
45namespace {
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
60bool ChromeShellDelegate::IsFirstRunAfterBoot() const {
61  return CommandLine::ForCurrentProcess()->HasSwitch(
62      chromeos::switches::kFirstExecAfterBoot);
63}
64
65void ChromeShellDelegate::PreInit() {
66  chromeos::LoadDisplayPreferences(IsFirstRunAfterBoot());
67}
68
69void ChromeShellDelegate::Shutdown() {
70  content::RecordAction(content::UserMetricsAction("Shutdown"));
71  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
72      RequestShutdown();
73}
74
75void ChromeShellDelegate::OpenFileManager(bool as_dialog) {
76  if (as_dialog) {
77    Browser* browser =
78        chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
79    // Open the select file dialog only if there is an active browser where the
80    // selected file is displayed.
81    if (browser) {
82      browser->OpenFile();
83      return;
84    }
85  } else {
86    using file_manager::kFileManagerAppId;
87    Profile* const profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
88    const apps::ShellWindowRegistry* const registry =
89        apps::ShellWindowRegistry::Get(profile);
90    const apps::ShellWindowRegistry::ShellWindowList list =
91        registry->GetShellWindowsForApp(kFileManagerAppId);
92    if (list.empty()) {
93      // Open the new window.
94      const ExtensionService* const service = profile->GetExtensionService();
95      if (service == NULL ||
96          !service->IsExtensionEnabledForLauncher(kFileManagerAppId))
97        return;
98      const extensions::Extension* const extension =
99          service->GetInstalledExtension(kFileManagerAppId);
100      // event_flags = 0 means this invokes the same behavior as the launcher
101      // item is clicked without any keyboard modifiers.
102      chrome::OpenApplication(
103          chrome::AppLaunchParams(profile, extension, 0 /* event_flags */));
104    } else {
105      // Activate the existing window.
106      list.front()->GetBaseWindow()->Activate();
107    }
108  }
109}
110
111void ChromeShellDelegate::OpenCrosh() {
112  GURL crosh_url = extensions::TerminalExtensionHelper::GetCroshExtensionURL(
113      ProfileManager::GetDefaultProfileOrOffTheRecord());
114  if (!crosh_url.is_valid())
115    return;
116  Browser* browser = GetTargetBrowser();
117  content::WebContents* page = browser->OpenURL(
118      content::OpenURLParams(crosh_url,
119                             content::Referrer(),
120                             NEW_FOREGROUND_TAB,
121                             content::PAGE_TRANSITION_GENERATED,
122                             false));
123  browser->window()->Show();
124  browser->window()->Activate();
125  page->GetView()->Focus();
126}
127
128void ChromeShellDelegate::ToggleHighContrast() {
129  DCHECK(chromeos::AccessibilityManager::Get());
130  bool enabled = chromeos::AccessibilityManager::Get()->IsHighContrastEnabled();
131  chromeos::AccessibilityManager::Get()->EnableHighContrast(!enabled);
132}
133
134bool ChromeShellDelegate::IsSpokenFeedbackEnabled() const {
135  DCHECK(chromeos::AccessibilityManager::Get());
136  return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
137}
138
139void ChromeShellDelegate::ToggleSpokenFeedback(
140    ash::AccessibilityNotificationVisibility notify) {
141  DCHECK(chromeos::AccessibilityManager::Get());
142  chromeos::AccessibilityManager::Get()->ToggleSpokenFeedback(notify);
143}
144
145bool ChromeShellDelegate::IsHighContrastEnabled() const {
146  DCHECK(chromeos::AccessibilityManager::Get());
147  return chromeos::AccessibilityManager::Get()->IsHighContrastEnabled();
148}
149
150bool ChromeShellDelegate::IsMagnifierEnabled() const {
151  DCHECK(chromeos::MagnificationManager::Get());
152  return chromeos::MagnificationManager::Get()->IsMagnifierEnabled();
153}
154
155ash::MagnifierType ChromeShellDelegate::GetMagnifierType() const {
156  DCHECK(chromeos::MagnificationManager::Get());
157  return chromeos::MagnificationManager::Get()->GetMagnifierType();
158}
159
160void ChromeShellDelegate::SetMagnifierEnabled(bool enabled) {
161  DCHECK(chromeos::MagnificationManager::Get());
162  return chromeos::MagnificationManager::Get()->SetMagnifierEnabled(enabled);
163}
164
165void ChromeShellDelegate::SetMagnifierType(ash::MagnifierType type) {
166  DCHECK(chromeos::MagnificationManager::Get());
167  return chromeos::MagnificationManager::Get()->SetMagnifierType(type);
168}
169
170void ChromeShellDelegate::SaveScreenMagnifierScale(double scale) {
171  if (chromeos::MagnificationManager::Get())
172    chromeos::MagnificationManager::Get()->SaveScreenMagnifierScale(scale);
173}
174
175double ChromeShellDelegate::GetSavedScreenMagnifierScale() {
176  if (chromeos::MagnificationManager::Get()) {
177    return chromeos::MagnificationManager::Get()->
178        GetSavedScreenMagnifierScale();
179  }
180  return std::numeric_limits<double>::min();
181}
182
183void ChromeShellDelegate::SetLargeCursorEnabled(bool enabled) {
184  DCHECK(chromeos::AccessibilityManager::Get());
185  return chromeos::AccessibilityManager::Get()->EnableLargeCursor(enabled);
186}
187
188bool ChromeShellDelegate::IsLargeCursorEnabled() const {
189  DCHECK(chromeos::AccessibilityManager::Get());
190  return chromeos::AccessibilityManager::Get()->IsLargeCursorEnabled();
191}
192
193ash::CapsLockDelegate* ChromeShellDelegate::CreateCapsLockDelegate() {
194  chromeos::input_method::XKeyboard* xkeyboard =
195      chromeos::input_method::InputMethodManager::Get()->GetXKeyboard();
196  return new CapsLockDelegate(xkeyboard);
197}
198
199ash::SessionStateDelegate* ChromeShellDelegate::CreateSessionStateDelegate() {
200  return new SessionStateDelegateChromeos;
201}
202
203void ChromeShellDelegate::ShowKeyboardOverlay() {
204  // TODO(mazda): Move the show logic to ash (http://crbug.com/124222).
205  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
206  std::string url(chrome::kChromeUIKeyboardOverlayURL);
207  ash::KeyboardOverlayView::ShowDialog(profile,
208                                       new ChromeWebContentsHandler,
209                                       GURL(url));
210}
211
212bool ChromeShellDelegate::ShouldAlwaysShowAccessibilityMenu() const {
213  Profile* profile = ProfileManager::GetDefaultProfile();
214  if (!profile)
215    return false;
216
217  PrefService* user_pref_service = profile->GetPrefs();
218  return user_pref_service &&
219      user_pref_service->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu);
220}
221
222void ChromeShellDelegate::SilenceSpokenFeedback() const {
223  TtsController::GetInstance()->Stop();
224}
225
226ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate() {
227  return chromeos::CreateSystemTrayDelegate();
228}
229
230ash::UserWallpaperDelegate* ChromeShellDelegate::CreateUserWallpaperDelegate() {
231  return chromeos::CreateUserWallpaperDelegate();
232}
233
234void ChromeShellDelegate::HandleMediaNextTrack() {
235  extensions::MediaPlayerAPI::Get(
236      ProfileManager::GetDefaultProfileOrOffTheRecord())->
237          media_player_event_router()->NotifyNextTrack();
238}
239
240void ChromeShellDelegate::HandleMediaPlayPause() {
241  extensions::MediaPlayerAPI::Get(
242      ProfileManager::GetDefaultProfileOrOffTheRecord())->
243          media_player_event_router()->NotifyTogglePlayState();
244}
245
246void ChromeShellDelegate::HandleMediaPrevTrack() {
247  extensions::MediaPlayerAPI::Get(
248      ProfileManager::GetDefaultProfileOrOffTheRecord())->
249          media_player_event_router()->NotifyPrevTrack();
250}
251
252void ChromeShellDelegate::Observe(int type,
253                                  const content::NotificationSource& source,
254                                  const content::NotificationDetails& details) {
255  switch (type) {
256    case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED:
257      ash::Shell::GetInstance()->CreateLauncher();
258      break;
259    case chrome::NOTIFICATION_SESSION_STARTED:
260      RestoreFocus();
261      ash::Shell::GetInstance()->ShowLauncher();
262      break;
263    default:
264      NOTREACHED() << "Unexpected notification " << type;
265  }
266}
267
268void ChromeShellDelegate::PlatformInit() {
269  registrar_.Add(this,
270                 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
271                 content::NotificationService::AllSources());
272  registrar_.Add(this,
273                 chrome::NOTIFICATION_SESSION_STARTED,
274                 content::NotificationService::AllSources());
275}
276