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/display_mode.h"
24 #include "ui/display/types/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
= nullptr;
39 // Screen object used during shutdown.
40 gfx::Screen
* screen_for_shutdown
= nullptr;
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 gfx::Point
GetCursorScreenPoint() override
{ return gfx::Point(); }
60 gfx::NativeWindow
GetWindowUnderCursor() override
{ return NULL
; }
61 gfx::NativeWindow
GetWindowAtScreenPoint(const gfx::Point
& point
) override
{
64 int GetNumDisplays() const override
{ return 1; }
65 std::vector
<gfx::Display
> GetAllDisplays() const override
{
66 std::vector
<gfx::Display
> displays(1, primary_display_
);
69 gfx::Display
GetDisplayNearestWindow(gfx::NativeView view
) const override
{
70 return primary_display_
;
72 gfx::Display
GetDisplayNearestPoint(const gfx::Point
& point
) const override
{
73 return primary_display_
;
75 gfx::Display
GetDisplayMatching(const gfx::Rect
& match_rect
) const override
{
76 return primary_display_
;
78 gfx::Display
GetPrimaryDisplay() const override
{ return primary_display_
; }
79 void AddObserver(gfx::DisplayObserver
* observer
) override
{
80 NOTREACHED() << "Observer should not be added during shutdown";
82 void RemoveObserver(gfx::DisplayObserver
* observer
) override
{}
84 const gfx::Display primary_display_
;
86 DISALLOW_COPY_AND_ASSIGN(ScreenForShutdown
);
89 // A class that bridges the gap between CursorManager and Aura. It borrows
90 // heavily from AshNativeCursorManager.
91 class AthenaNativeCursorManager
: public wm::NativeCursorManager
{
93 explicit AthenaNativeCursorManager(aura::WindowTreeHost
* host
)
94 : host_(host
), image_cursors_(new ui::ImageCursors
) {}
95 ~AthenaNativeCursorManager() override
{}
97 // wm::NativeCursorManager overrides.
98 void SetDisplay(const gfx::Display
& display
,
99 wm::NativeCursorManagerDelegate
* delegate
) override
{
100 if (image_cursors_
->SetDisplay(display
, display
.device_scale_factor()))
101 SetCursor(delegate
->GetCursor(), delegate
);
104 void SetCursor(gfx::NativeCursor cursor
,
105 wm::NativeCursorManagerDelegate
* delegate
) override
{
106 image_cursors_
->SetPlatformCursor(&cursor
);
107 cursor
.set_device_scale_factor(image_cursors_
->GetScale());
108 delegate
->CommitCursor(cursor
);
110 if (delegate
->IsCursorVisible())
114 void SetVisibility(bool visible
,
115 wm::NativeCursorManagerDelegate
* delegate
) override
{
116 delegate
->CommitVisibility(visible
);
119 SetCursor(delegate
->GetCursor(), delegate
);
121 gfx::NativeCursor
invisible_cursor(ui::kCursorNone
);
122 image_cursors_
->SetPlatformCursor(&invisible_cursor
);
123 ApplyCursor(invisible_cursor
);
127 void SetCursorSet(ui::CursorSetType cursor_set
,
128 wm::NativeCursorManagerDelegate
* delegate
) override
{
129 image_cursors_
->SetCursorSet(cursor_set
);
130 delegate
->CommitCursorSet(cursor_set
);
131 if (delegate
->IsCursorVisible())
132 SetCursor(delegate
->GetCursor(), delegate
);
135 void SetMouseEventsEnabled(
137 wm::NativeCursorManagerDelegate
* delegate
) override
{
138 delegate
->CommitMouseEventsEnabled(enabled
);
139 SetVisibility(delegate
->IsCursorVisible(), delegate
);
143 // Sets |cursor| as the active cursor within Aura.
144 void ApplyCursor(gfx::NativeCursor cursor
) { host_
->SetCursor(cursor
); }
146 aura::WindowTreeHost
* host_
; // Not owned.
148 scoped_ptr
<ui::ImageCursors
> image_cursors_
;
150 DISALLOW_COPY_AND_ASSIGN(AthenaNativeCursorManager
);
153 class AthenaEnvImpl
: public AthenaEnv
,
154 public aura::WindowTreeHostObserver
,
155 public ui::DisplayConfigurator::Observer
{
157 AthenaEnvImpl() : display_configurator_(new ui::DisplayConfigurator
) {
158 display_configurator_
->Init(false);
159 display_configurator_
->ForceInitialConfigure(0);
160 display_configurator_
->AddObserver(this);
162 gfx::Size screen_size
= GetPrimaryDisplaySize();
163 if (screen_size
.IsEmpty()) {
164 // TODO(oshima): Remove this hack.
165 if (base::SysInfo::IsRunningOnChromeOS())
166 screen_size
.SetSize(2560, 1600);
168 screen_size
.SetSize(1280, 720);
170 screen_
.reset(aura::TestScreen::Create(screen_size
));
172 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
173 host_
.reset(screen_
->CreateHostForPrimaryDisplay());
176 aura::Window
* root_window
= GetHost()->window();
177 input_method_filter_
.reset(
178 new wm::InputMethodEventFilter(host_
->GetAcceleratedWidget()));
179 input_method_filter_
->SetInputMethodPropertyInRootWindow(root_window
);
181 root_window_event_filter_
.reset(new wm::CompoundEventFilter
);
182 host_
->window()->AddPreTargetHandler(root_window_event_filter_
.get());
184 root_window_event_filter_
->AddHandler(input_method_filter_
.get());
186 capture_client_
.reset(
187 new aura::client::DefaultCaptureClient(host_
->window()));
189 // Ensure new windows fill the display.
190 root_window
->SetLayoutManager(new FillLayoutManager(root_window
));
192 cursor_manager_
.reset(
193 new wm::CursorManager(scoped_ptr
<wm::NativeCursorManager
>(
194 new AthenaNativeCursorManager(host_
.get()))));
195 cursor_manager_
->SetDisplay(
196 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay());
197 cursor_manager_
->SetCursor(ui::kCursorPointer
);
198 aura::client::SetCursorClient(host_
->window(), cursor_manager_
.get());
200 user_activity_detector_
.reset(new wm::UserActivityDetector
);
201 host_
->event_processor()->GetRootTarget()->AddPreTargetHandler(
202 user_activity_detector_
.get());
203 user_activity_notifier_
.reset(new ui::UserActivityPowerManagerNotifier(
204 user_activity_detector_
.get()));
206 host_
->AddObserver(this);
213 ~AthenaEnvImpl() override
{
216 host_
->RemoveObserver(this);
217 if (input_method_filter_
)
218 root_window_event_filter_
->RemoveHandler(input_method_filter_
.get());
219 if (user_activity_detector_
) {
220 host_
->event_processor()->GetRootTarget()->RemovePreTargetHandler(
221 user_activity_detector_
.get());
223 root_window_event_filter_
.reset();
224 capture_client_
.reset();
225 input_method_filter_
.reset();
226 cursor_manager_
.reset();
227 user_activity_notifier_
.reset();
228 user_activity_detector_
.reset();
230 input_method_filter_
.reset();
233 ScreenForShutdown::Create(screen_
.get());
235 aura::Env::DeleteInstance();
237 display_configurator_
->RemoveObserver(this);
238 display_configurator_
.reset();
243 explicit Finder(const base::Closure
& c
) : closure(c
) {}
244 bool operator()(const base::Closure
& other
) {
245 return closure
.Equals(other
);
247 base::Closure closure
;
251 aura::WindowTreeHost
* GetHost() override
{ return host_
.get(); }
253 void SetDisplayWorkAreaInsets(const gfx::Insets
& insets
) override
{
254 screen_
->SetWorkAreaInsets(insets
);
257 void AddTerminatingCallback(const base::Closure
& closure
) override
{
258 if (closure
.is_null())
260 DCHECK(terminating_callbacks_
.end() ==
261 std::find_if(terminating_callbacks_
.begin(),
262 terminating_callbacks_
.end(),
264 terminating_callbacks_
.push_back(closure
);
267 void RemoveTerminatingCallback(const base::Closure
& closure
) override
{
268 std::vector
<base::Closure
>::iterator iter
=
269 std::find_if(terminating_callbacks_
.begin(),
270 terminating_callbacks_
.end(),
272 if (iter
!= terminating_callbacks_
.end())
273 terminating_callbacks_
.erase(iter
);
276 void OnTerminating() override
{
277 for (std::vector
<base::Closure
>::iterator iter
=
278 terminating_callbacks_
.begin();
279 iter
!= terminating_callbacks_
.end();
285 // ui::DisplayConfigurator::Observer:
286 void OnDisplayModeChanged(
287 const std::vector
<ui::DisplayConfigurator::DisplayState
>& displays
)
289 gfx::Size size
= GetPrimaryDisplaySize();
291 host_
->UpdateRootWindowSize(size
);
294 // aura::WindowTreeHostObserver:
295 void OnHostCloseRequested(const aura::WindowTreeHost
* host
) override
{
296 base::MessageLoopForUI::current()->PostTask(
297 FROM_HERE
, base::MessageLoop::QuitClosure());
300 gfx::Size
GetPrimaryDisplaySize() const {
301 const std::vector
<ui::DisplayConfigurator::DisplayState
>& displays
=
302 display_configurator_
->cached_displays();
303 if (displays
.empty())
305 const ui::DisplayMode
* mode
= displays
[0].display
->current_mode();
306 return mode
? mode
->size() : gfx::Size();
309 scoped_ptr
<aura::TestScreen
> screen_
;
310 scoped_ptr
<aura::WindowTreeHost
> host_
;
312 scoped_ptr
<wm::InputMethodEventFilter
> input_method_filter_
;
313 scoped_ptr
<wm::CompoundEventFilter
> root_window_event_filter_
;
314 scoped_ptr
<aura::client::DefaultCaptureClient
> capture_client_
;
315 scoped_ptr
<wm::CursorManager
> cursor_manager_
;
316 scoped_ptr
<wm::UserActivityDetector
> user_activity_detector_
;
317 scoped_ptr
<ui::DisplayConfigurator
> display_configurator_
;
318 scoped_ptr
<ui::UserActivityPowerManagerNotifier
> user_activity_notifier_
;
320 std::vector
<base::Closure
> terminating_callbacks_
;
322 DISALLOW_COPY_AND_ASSIGN(AthenaEnvImpl
);
328 void AthenaEnv::Create() {
333 AthenaEnv
* AthenaEnv::Get() {
341 void AthenaEnv::Shutdown() {
346 } // namespace athena