Add Search Service in Enhanced Bookmark Bridge
[chromium-blink-merge.git] / athena / env / athena_env_impl.cc
blob326b950cc567c1ca9abecd5095db12aa67c42ef9
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"
7 #include <vector>
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"
33 namespace athena {
35 namespace {
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 {
45 public:
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,
51 screen_for_shutdown);
54 private:
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 {
62 return nullptr;
64 int GetNumDisplays() const override { return 1; }
65 std::vector<gfx::Display> GetAllDisplays() const override {
66 std::vector<gfx::Display> displays(1, primary_display_);
67 return displays;
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 {
92 public:
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())
111 ApplyCursor(cursor);
114 void SetVisibility(bool visible,
115 wm::NativeCursorManagerDelegate* delegate) override {
116 delegate->CommitVisibility(visible);
118 if (visible) {
119 SetCursor(delegate->GetCursor(), delegate);
120 } else {
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(
136 bool enabled,
137 wm::NativeCursorManagerDelegate* delegate) override {
138 delegate->CommitMouseEventsEnabled(enabled);
139 SetVisibility(delegate->IsCursorVisible(), delegate);
142 private:
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 {
156 public:
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);
167 else
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());
174 host_->InitHost();
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);
207 host_->Show();
209 DCHECK(!instance);
210 instance = this;
213 ~AthenaEnvImpl() override {
214 instance = nullptr;
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();
231 host_.reset();
233 ScreenForShutdown::Create(screen_.get());
234 screen_.reset();
235 aura::Env::DeleteInstance();
237 display_configurator_->RemoveObserver(this);
238 display_configurator_.reset();
241 private:
242 struct Finder {
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;
250 // AthenaEnv:
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())
259 return;
260 DCHECK(terminating_callbacks_.end() ==
261 std::find_if(terminating_callbacks_.begin(),
262 terminating_callbacks_.end(),
263 Finder(closure)));
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(),
271 Finder(closure));
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();
280 ++iter) {
281 iter->Run();
285 // ui::DisplayConfigurator::Observer:
286 void OnDisplayModeChanged(
287 const std::vector<ui::DisplayConfigurator::DisplayState>& displays)
288 override {
289 gfx::Size size = GetPrimaryDisplaySize();
290 if (!size.IsEmpty())
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())
304 return gfx::Size();
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);
325 } // namespace
327 // static
328 void AthenaEnv::Create() {
329 DCHECK(!instance);
330 new AthenaEnvImpl();
333 AthenaEnv* AthenaEnv::Get() {
334 DCHECK(instance);
335 return instance;
338 // static
340 // static
341 void AthenaEnv::Shutdown() {
342 DCHECK(instance);
343 delete instance;
346 } // namespace athena