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 <vector>
8
9#include "ash/accessibility_delegate.h"
10#include "ash/magnifier/magnifier_constants.h"
11#include "ash/media_delegate.h"
12#include "ash/system/tray/default_system_tray_delegate.h"
13#include "ash/wm/window_util.h"
14#include "base/command_line.h"
15#include "chrome/browser/accessibility/accessibility_events.h"
16#include "chrome/browser/browser_process.h"
17#include "chrome/browser/chrome_notification_types.h"
18#include "chrome/browser/prefs/session_startup_pref.h"
19#include "chrome/browser/profiles/profile.h"
20#include "chrome/browser/profiles/profile_manager.h"
21#include "chrome/browser/signin/signin_error_notifier_factory_ash.h"
22#include "chrome/browser/sync/sync_error_notifier_factory_ash.h"
23#include "chrome/browser/ui/ash/chrome_new_window_delegate.h"
24#include "chrome/browser/ui/ash/session_state_delegate_views.h"
25#include "chrome/browser/ui/ash/solid_color_user_wallpaper_delegate.h"
26#include "chrome/browser/ui/browser.h"
27#include "chrome/browser/ui/browser_finder.h"
28#include "chrome/browser/ui/browser_list.h"
29#include "chrome/browser/ui/browser_tabstrip.h"
30#include "chrome/browser/ui/browser_window.h"
31#include "chrome/browser/ui/host_desktop.h"
32#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
33#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
34#include "chrome/common/chrome_switches.h"
35#include "content/public/browser/notification_service.h"
36
37#if defined(OS_WIN)
38#include "chrome/browser/ui/ash/system_tray_delegate_win.h"
39#endif
40
41#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
42#include "chrome/browser/ui/ash/system_tray_delegate_linux.h"
43#endif
44
45namespace {
46
47class NewWindowDelegateImpl : public ChromeNewWindowDelegate {
48 public:
49  NewWindowDelegateImpl() {}
50  virtual ~NewWindowDelegateImpl() {}
51
52  // Overridden from ash::NewWindowDelegate:
53  virtual void OpenFileManager() OVERRIDE {}
54  virtual void OpenCrosh() OVERRIDE {}
55  virtual void ShowKeyboardOverlay() OVERRIDE {}
56
57 private:
58  DISALLOW_COPY_AND_ASSIGN(NewWindowDelegateImpl);
59};
60
61class MediaDelegateImpl : public ash::MediaDelegate {
62 public:
63  MediaDelegateImpl() {}
64  virtual ~MediaDelegateImpl() {}
65  virtual void HandleMediaNextTrack() OVERRIDE {}
66  virtual void HandleMediaPlayPause() OVERRIDE {}
67  virtual void HandleMediaPrevTrack() OVERRIDE {}
68  virtual ash::MediaCaptureState GetMediaCaptureState(
69      content::BrowserContext* context) OVERRIDE {
70    return ash::MEDIA_CAPTURE_NONE;
71  }
72
73 private:
74  DISALLOW_COPY_AND_ASSIGN(MediaDelegateImpl);
75};
76
77class EmptyAccessibilityDelegate : public ash::AccessibilityDelegate {
78 public:
79  EmptyAccessibilityDelegate() {}
80  virtual ~EmptyAccessibilityDelegate() {}
81
82  virtual void ToggleHighContrast() OVERRIDE {
83  }
84
85  virtual bool IsHighContrastEnabled() const OVERRIDE {
86    return false;
87  }
88
89  virtual bool IsSpokenFeedbackEnabled() const OVERRIDE {
90    return false;
91  }
92
93  virtual void ToggleSpokenFeedback(
94      ash::AccessibilityNotificationVisibility notify) OVERRIDE {
95  }
96
97  virtual void SetLargeCursorEnabled(bool enalbed) OVERRIDE {
98  }
99
100  virtual bool IsLargeCursorEnabled() const OVERRIDE {
101    return false;
102  }
103
104  virtual void SetMagnifierEnabled(bool enabled) OVERRIDE {
105  }
106
107  virtual void SetMagnifierType(ash::MagnifierType type) OVERRIDE {
108  }
109
110  virtual bool IsMagnifierEnabled() const OVERRIDE {
111    return false;
112  }
113
114  virtual void SetAutoclickEnabled(bool enabled) OVERRIDE {
115  }
116
117  virtual bool IsAutoclickEnabled() const OVERRIDE {
118    return false;
119  }
120
121  virtual ash::MagnifierType GetMagnifierType() const OVERRIDE {
122    return ash::kDefaultMagnifierType;
123  }
124
125  virtual void SaveScreenMagnifierScale(double scale) OVERRIDE {
126  }
127
128  virtual double GetSavedScreenMagnifierScale() OVERRIDE {
129    return std::numeric_limits<double>::min();
130  }
131
132  virtual bool ShouldShowAccessibilityMenu() const OVERRIDE {
133    return false;
134  }
135
136  virtual bool IsBrailleDisplayConnected() const OVERRIDE { return false; }
137
138  virtual void SilenceSpokenFeedback() const OVERRIDE {
139  }
140
141  virtual void SetVirtualKeyboardEnabled(bool enabled) OVERRIDE {
142  }
143
144  virtual bool IsVirtualKeyboardEnabled() const OVERRIDE {
145    return false;
146  }
147
148  virtual void TriggerAccessibilityAlert(
149      ash::AccessibilityAlert alert) OVERRIDE {
150  }
151
152  virtual ash::AccessibilityAlert GetLastAccessibilityAlert() OVERRIDE {
153    return ash::A11Y_ALERT_NONE;
154  }
155
156  virtual void PlayEarcon(int sound_key) OVERRIDE {
157  }
158
159  virtual base::TimeDelta PlayShutdownSound() const OVERRIDE {
160    return base::TimeDelta();
161  }
162
163 private:
164  DISALLOW_COPY_AND_ASSIGN(EmptyAccessibilityDelegate);
165};
166
167}  // namespace
168
169bool ChromeShellDelegate::IsFirstRunAfterBoot() const {
170  return false;
171}
172
173void ChromeShellDelegate::PreInit() {
174}
175
176void ChromeShellDelegate::PreShutdown() {
177}
178
179ash::NewWindowDelegate* ChromeShellDelegate::CreateNewWindowDelegate() {
180  return new NewWindowDelegateImpl;
181}
182
183ash::MediaDelegate* ChromeShellDelegate::CreateMediaDelegate() {
184  return new MediaDelegateImpl;
185}
186
187ash::SessionStateDelegate* ChromeShellDelegate::CreateSessionStateDelegate() {
188  return new SessionStateDelegate;
189}
190
191ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate() {
192#if defined(OS_WIN)
193  return CreateWindowsSystemTrayDelegate();
194#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
195  return CreateLinuxSystemTrayDelegate();
196#else
197  return new ash::DefaultSystemTrayDelegate;
198#endif
199}
200
201ash::AccessibilityDelegate* ChromeShellDelegate::CreateAccessibilityDelegate() {
202  return new EmptyAccessibilityDelegate;
203}
204
205ash::UserWallpaperDelegate* ChromeShellDelegate::CreateUserWallpaperDelegate() {
206  return CreateSolidColorUserWallpaperDelegate();
207}
208
209void ChromeShellDelegate::Observe(int type,
210                                  const content::NotificationSource& source,
211                                  const content::NotificationDetails& details) {
212  switch (type) {
213    case chrome::NOTIFICATION_PROFILE_ADDED: {
214      // Start the error notifier services to show sync/auth notifications.
215      Profile* profile = content::Source<Profile>(source).ptr();
216      SigninErrorNotifierFactory::GetForProfile(profile);
217      SyncErrorNotifierFactory::GetForProfile(profile);
218      break;
219    }
220    case chrome::NOTIFICATION_ASH_SESSION_STARTED: {
221      // Start the error notifier services for the already loaded profiles.
222      const std::vector<Profile*> profiles =
223          g_browser_process->profile_manager()->GetLoadedProfiles();
224      for (std::vector<Profile*>::const_iterator it = profiles.begin();
225           it != profiles.end(); ++it) {
226        SigninErrorNotifierFactory::GetForProfile(*it);
227        SyncErrorNotifierFactory::GetForProfile(*it);
228      }
229
230#if defined(OS_WIN)
231      // If we are launched to service a windows 8 search request then let the
232      // IPC which carries the search string create the browser and initiate
233      // the navigation.
234      if (CommandLine::ForCurrentProcess()->HasSwitch(
235          switches::kWindows8Search))
236        break;
237#endif
238      // If Chrome ASH is launched when no browser is open in the desktop,
239      // we should execute the startup code.
240      // If there are browsers open in the desktop, we create a browser window
241      // and open a new tab page, if session restore is not on.
242      BrowserList* desktop_list = BrowserList::GetInstance(
243          chrome::HOST_DESKTOP_TYPE_NATIVE);
244      if (desktop_list->empty()) {
245        // We pass a dummy command line here, because the browser is launched in
246        // silent-mode by the metro viewer process, which causes the
247        // StartupBrowserCreatorImpl class to not create any browsers which is
248        // not the behavior we want.
249        CommandLine dummy(CommandLine::NO_PROGRAM);
250        StartupBrowserCreatorImpl startup_impl(
251            base::FilePath(),
252            dummy,
253            chrome::startup::IS_NOT_FIRST_RUN);
254        startup_impl.Launch(
255            ProfileManager::GetActiveUserProfile(),
256            std::vector<GURL>(),
257            true,
258            chrome::HOST_DESKTOP_TYPE_ASH);
259      } else {
260        Browser* browser =
261            chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
262        if (browser && browser->is_type_tabbed()) {
263          chrome::AddTabAt(browser, GURL(), -1, true);
264          return;
265        }
266
267        chrome::ScopedTabbedBrowserDisplayer displayer(
268            ProfileManager::GetActiveUserProfile(),
269            chrome::HOST_DESKTOP_TYPE_ASH);
270        chrome::AddTabAt(displayer.browser(), GURL(), -1, true);
271      }
272      break;
273    }
274    case chrome::NOTIFICATION_ASH_SESSION_ENDED:
275      break;
276    default:
277      NOTREACHED() << "Unexpected notification " << type;
278  }
279}
280
281void ChromeShellDelegate::PlatformInit() {
282#if defined(OS_WIN)
283  registrar_.Add(this,
284                 chrome::NOTIFICATION_PROFILE_ADDED,
285                 content::NotificationService::AllSources());
286  registrar_.Add(this,
287                 chrome::NOTIFICATION_ASH_SESSION_STARTED,
288                 content::NotificationService::AllSources());
289  registrar_.Add(this,
290                 chrome::NOTIFICATION_ASH_SESSION_ENDED,
291                 content::NotificationService::AllSources());
292#endif
293}
294