1 // Copyright 2014 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.
5 #include "athena/env/public/athena_env.h"
9 #include "athena/util/fill_layout_manager.h"
10 #include "base/sys_info.h"
11 #include "ui/aura/client/aura_constants.h"
12 #include "ui/aura/client/cursor_client.h"
13 #include "ui/aura/client/default_capture_client.h"
14 #include "ui/aura/env.h"
15 #include "ui/aura/test/test_screen.h"
16 #include "ui/aura/window_event_dispatcher.h"
17 #include "ui/aura/window_tree_host.h"
18 #include "ui/aura/window_tree_host_observer.h"
19 #include "ui/base/cursor/cursor.h"
20 #include "ui/base/cursor/image_cursors.h"
21 #include "ui/chromeos/user_activity_power_manager_notifier.h"
22 #include "ui/display/chromeos/display_configurator.h"
23 #include "ui/display/types/chromeos/display_mode.h"
24 #include "ui/display/types/chromeos/display_snapshot.h"
25 #include "ui/gfx/screen.h"
26 #include "ui/wm/core/compound_event_filter.h"
27 #include "ui/wm/core/cursor_manager.h"
28 #include "ui/wm/core/input_method_event_filter.h"
29 #include "ui/wm/core/native_cursor_manager.h"
30 #include "ui/wm/core/native_cursor_manager_delegate.h"
31 #include "ui/wm/core/user_activity_detector.h"
37 AthenaEnv
* instance
= NULL
;
39 // Screen object used during shutdown.
40 gfx::Screen
* screen_for_shutdown
= NULL
;
42 // TODO(flackr:oshima): Remove this once athena switches to share
43 // ash::DisplayManager.
44 class ScreenForShutdown
: public gfx::Screen
{
46 // Creates and sets the screen for shutdown. Deletes existing one if any.
47 static void Create(const gfx::Screen
* screen
) {
48 delete screen_for_shutdown
;
49 screen_for_shutdown
= new ScreenForShutdown(screen
->GetPrimaryDisplay());
50 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
,
55 explicit ScreenForShutdown(const gfx::Display
& primary_display
)
56 : primary_display_(primary_display
) {}
58 // gfx::Screen overrides:
59 virtual bool IsDIPEnabled() OVERRIDE
{ return true; }
60 virtual gfx::Point
GetCursorScreenPoint() OVERRIDE
{ return gfx::Point(); }
61 virtual gfx::NativeWindow
GetWindowUnderCursor() OVERRIDE
{ return NULL
; }
62 virtual gfx::NativeWindow
GetWindowAtScreenPoint(
63 const gfx::Point
& point
) OVERRIDE
{
66 virtual int GetNumDisplays() const OVERRIDE
{ return 1; }
67 virtual std::vector
<gfx::Display
> GetAllDisplays() const OVERRIDE
{
68 std::vector
<gfx::Display
> displays(1, primary_display_
);
71 virtual gfx::Display
GetDisplayNearestWindow(
72 gfx::NativeView view
) const OVERRIDE
{
73 return primary_display_
;
75 virtual gfx::Display
GetDisplayNearestPoint(
76 const gfx::Point
& point
) const OVERRIDE
{
77 return primary_display_
;
79 virtual gfx::Display
GetDisplayMatching(
80 const gfx::Rect
& match_rect
) const OVERRIDE
{
81 return primary_display_
;
83 virtual gfx::Display
GetPrimaryDisplay() const OVERRIDE
{
84 return primary_display_
;
86 virtual void AddObserver(gfx::DisplayObserver
* observer
) OVERRIDE
{
87 NOTREACHED() << "Observer should not be added during shutdown";
89 virtual void RemoveObserver(gfx::DisplayObserver
* observer
) OVERRIDE
{}
91 const gfx::Display primary_display_
;
93 DISALLOW_COPY_AND_ASSIGN(ScreenForShutdown
);
96 // A class that bridges the gap between CursorManager and Aura. It borrows
97 // heavily from AshNativeCursorManager.
98 class AthenaNativeCursorManager
: public wm::NativeCursorManager
{
100 explicit AthenaNativeCursorManager(aura::WindowTreeHost
* host
)
101 : host_(host
), image_cursors_(new ui::ImageCursors
) {}
102 virtual ~AthenaNativeCursorManager() {}
104 // wm::NativeCursorManager overrides.
105 virtual void SetDisplay(const gfx::Display
& display
,
106 wm::NativeCursorManagerDelegate
* delegate
) OVERRIDE
{
107 if (image_cursors_
->SetDisplay(display
, display
.device_scale_factor()))
108 SetCursor(delegate
->GetCursor(), delegate
);
111 virtual void SetCursor(gfx::NativeCursor cursor
,
112 wm::NativeCursorManagerDelegate
* delegate
) OVERRIDE
{
113 image_cursors_
->SetPlatformCursor(&cursor
);
114 cursor
.set_device_scale_factor(image_cursors_
->GetScale());
115 delegate
->CommitCursor(cursor
);
117 if (delegate
->IsCursorVisible())
121 virtual void SetVisibility(
123 wm::NativeCursorManagerDelegate
* delegate
) OVERRIDE
{
124 delegate
->CommitVisibility(visible
);
127 SetCursor(delegate
->GetCursor(), delegate
);
129 gfx::NativeCursor
invisible_cursor(ui::kCursorNone
);
130 image_cursors_
->SetPlatformCursor(&invisible_cursor
);
131 ApplyCursor(invisible_cursor
);
135 virtual void SetCursorSet(
136 ui::CursorSetType cursor_set
,
137 wm::NativeCursorManagerDelegate
* delegate
) OVERRIDE
{
138 image_cursors_
->SetCursorSet(cursor_set
);
139 delegate
->CommitCursorSet(cursor_set
);
140 if (delegate
->IsCursorVisible())
141 SetCursor(delegate
->GetCursor(), delegate
);
144 virtual void SetMouseEventsEnabled(
146 wm::NativeCursorManagerDelegate
* delegate
) OVERRIDE
{
147 delegate
->CommitMouseEventsEnabled(enabled
);
148 SetVisibility(delegate
->IsCursorVisible(), delegate
);
152 // Sets |cursor| as the active cursor within Aura.
153 void ApplyCursor(gfx::NativeCursor cursor
) { host_
->SetCursor(cursor
); }
155 aura::WindowTreeHost
* host_
; // Not owned.
157 scoped_ptr
<ui::ImageCursors
> image_cursors_
;
159 DISALLOW_COPY_AND_ASSIGN(AthenaNativeCursorManager
);
162 class AthenaEnvImpl
: public AthenaEnv
,
163 public aura::WindowTreeHostObserver
,
164 public ui::DisplayConfigurator::Observer
{
166 AthenaEnvImpl() : display_configurator_(new ui::DisplayConfigurator
) {
167 display_configurator_
->Init(false);
168 display_configurator_
->ForceInitialConfigure(0);
169 display_configurator_
->AddObserver(this);
171 gfx::Size screen_size
= GetPrimaryDisplaySize();
172 if (screen_size
.IsEmpty()) {
173 // TODO(oshima): Remove this hack.
174 if (base::SysInfo::IsRunningOnChromeOS())
175 screen_size
.SetSize(2560, 1600);
177 screen_size
.SetSize(1280, 720);
179 screen_
.reset(aura::TestScreen::Create(screen_size
));
181 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
182 host_
.reset(screen_
->CreateHostForPrimaryDisplay());
185 aura::Window
* root_window
= GetHost()->window();
186 input_method_filter_
.reset(
187 new wm::InputMethodEventFilter(host_
->GetAcceleratedWidget()));
188 input_method_filter_
->SetInputMethodPropertyInRootWindow(root_window
);
190 root_window_event_filter_
.reset(new wm::CompoundEventFilter
);
191 host_
->window()->AddPreTargetHandler(root_window_event_filter_
.get());
193 input_method_filter_
.reset(
194 new wm::InputMethodEventFilter(host_
->GetAcceleratedWidget()));
195 input_method_filter_
->SetInputMethodPropertyInRootWindow(host_
->window());
196 root_window_event_filter_
->AddHandler(input_method_filter_
.get());
198 capture_client_
.reset(
199 new aura::client::DefaultCaptureClient(host_
->window()));
201 // Ensure new windows fill the display.
202 root_window
->SetLayoutManager(new FillLayoutManager(root_window
));
204 cursor_manager_
.reset(
205 new wm::CursorManager(scoped_ptr
<wm::NativeCursorManager
>(
206 new AthenaNativeCursorManager(host_
.get()))));
207 cursor_manager_
->SetDisplay(
208 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay());
209 cursor_manager_
->SetCursor(ui::kCursorPointer
);
210 aura::client::SetCursorClient(host_
->window(), cursor_manager_
.get());
212 user_activity_detector_
.reset(new wm::UserActivityDetector
);
213 host_
->event_processor()->GetRootTarget()->AddPreTargetHandler(
214 user_activity_detector_
.get());
215 user_activity_notifier_
.reset(new ui::UserActivityPowerManagerNotifier(
216 user_activity_detector_
.get()));
218 host_
->AddObserver(this);
225 virtual ~AthenaEnvImpl() {
228 host_
->RemoveObserver(this);
229 if (input_method_filter_
)
230 root_window_event_filter_
->RemoveHandler(input_method_filter_
.get());
231 if (user_activity_detector_
) {
232 host_
->event_processor()->GetRootTarget()->RemovePreTargetHandler(
233 user_activity_detector_
.get());
235 root_window_event_filter_
.reset();
236 capture_client_
.reset();
237 input_method_filter_
.reset();
238 cursor_manager_
.reset();
239 user_activity_notifier_
.reset();
240 user_activity_detector_
.reset();
242 input_method_filter_
.reset();
245 ScreenForShutdown::Create(screen_
.get());
247 aura::Env::DeleteInstance();
249 display_configurator_
->RemoveObserver(this);
250 display_configurator_
.reset();
255 explicit Finder(const base::Closure
& c
) : closure(c
) {}
256 bool operator()(const base::Closure
& other
) {
257 return closure
.Equals(other
);
259 base::Closure closure
;
263 virtual aura::WindowTreeHost
* GetHost() OVERRIDE
{ return host_
.get(); }
265 virtual void SetDisplayWorkAreaInsets(const gfx::Insets
& insets
) OVERRIDE
{
266 screen_
->SetWorkAreaInsets(insets
);
269 virtual void AddTerminatingCallback(const base::Closure
& closure
) OVERRIDE
{
270 if (closure
.is_null())
272 DCHECK(terminating_callbacks_
.end() ==
273 std::find_if(terminating_callbacks_
.begin(),
274 terminating_callbacks_
.end(),
276 terminating_callbacks_
.push_back(closure
);
279 virtual void RemoveTerminatingCallback(
280 const base::Closure
& closure
) OVERRIDE
{
281 std::vector
<base::Closure
>::iterator iter
=
282 std::find_if(terminating_callbacks_
.begin(),
283 terminating_callbacks_
.end(),
285 if (iter
!= terminating_callbacks_
.end())
286 terminating_callbacks_
.erase(iter
);
289 virtual void OnTerminating() OVERRIDE
{
290 for (std::vector
<base::Closure
>::iterator iter
=
291 terminating_callbacks_
.begin();
292 iter
!= terminating_callbacks_
.end();
298 // ui::DisplayConfigurator::Observer:
299 virtual void OnDisplayModeChanged(const std::vector
<
300 ui::DisplayConfigurator::DisplayState
>& displays
) OVERRIDE
{
301 gfx::Size size
= GetPrimaryDisplaySize();
303 host_
->UpdateRootWindowSize(size
);
306 // aura::WindowTreeHostObserver:
307 virtual void OnHostCloseRequested(const aura::WindowTreeHost
* host
) OVERRIDE
{
308 base::MessageLoopForUI::current()->PostTask(
309 FROM_HERE
, base::MessageLoop::QuitClosure());
312 gfx::Size
GetPrimaryDisplaySize() const {
313 const std::vector
<ui::DisplayConfigurator::DisplayState
>& displays
=
314 display_configurator_
->cached_displays();
315 if (displays
.empty())
317 const ui::DisplayMode
* mode
= displays
[0].display
->current_mode();
318 return mode
? mode
->size() : gfx::Size();
321 scoped_ptr
<aura::TestScreen
> screen_
;
322 scoped_ptr
<aura::WindowTreeHost
> host_
;
324 scoped_ptr
<wm::InputMethodEventFilter
> input_method_filter_
;
325 scoped_ptr
<wm::CompoundEventFilter
> root_window_event_filter_
;
326 scoped_ptr
<aura::client::DefaultCaptureClient
> capture_client_
;
327 scoped_ptr
<wm::CursorManager
> cursor_manager_
;
328 scoped_ptr
<wm::UserActivityDetector
> user_activity_detector_
;
329 scoped_ptr
<ui::DisplayConfigurator
> display_configurator_
;
330 scoped_ptr
<ui::UserActivityPowerManagerNotifier
> user_activity_notifier_
;
332 std::vector
<base::Closure
> terminating_callbacks_
;
334 DISALLOW_COPY_AND_ASSIGN(AthenaEnvImpl
);
340 void AthenaEnv::Create() {
345 AthenaEnv
* AthenaEnv::Get() {
353 void AthenaEnv::Shutdown() {
358 } // namespace athena