1 // Copyright (c) 2012 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 "ui/aura/env.h"
6
7 #include "base/command_line.h"
8 #include "base/lazy_instance.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/observer_list_types.h"
11 #include "ui/aura/client/aura_constants.h"
12 #include "ui/aura/env_input_state_controller.h"
13 #include "ui/aura/env_observer.h"
14 #include "ui/aura/input_state_lookup.h"
15 #include "ui/aura/window.h"
16 #include "ui/aura/window_event_dispatcher_observer.h"
17 #include "ui/aura/window_occlusion_tracker.h"
18 #include "ui/base/ui_base_features.h"
19 #include "ui/events/event_observer.h"
20 #include "ui/events/event_target_iterator.h"
21 #include "ui/events/gestures/gesture_recognizer_impl.h"
22 #include "ui/events/platform/platform_event_source.h"
23
24 #if defined(USE_OZONE)
25 #include "ui/ozone/public/ozone_platform.h"
26 #endif
27
28 #if defined(USE_X11)
29 #include "ui/gfx/switches.h"
30 #endif
31
32 namespace aura {
33
34 namespace {
35
36 // Instance created by all static functions, except
37 // CreateLocalInstanceForInProcess(). See GetInstance() for details.
38 Env* g_primary_instance = nullptr;
39
40 } // namespace
41
42 // EventObserverAdapter is an aura::Env pre-target handler that forwards
43 // read-only events to its observer when they match the requested types.
44 class EventObserverAdapter : public ui::EventHandler,
45 public base::CheckedObserver {
46 public:
EventObserverAdapter(ui::EventObserver * observer,ui::EventTarget * target,const std::set<ui::EventType> & types)47 EventObserverAdapter(ui::EventObserver* observer,
48 ui::EventTarget* target,
49 const std::set<ui::EventType>& types)
50 : observer_(observer), target_(target), types_(types) {
51 target_->AddPreTargetHandler(this);
52 }
53
~EventObserverAdapter()54 ~EventObserverAdapter() override { target_->RemovePreTargetHandler(this); }
55
observer()56 ui::EventObserver* observer() { return observer_; }
target()57 ui::EventTarget* target() { return target_; }
types() const58 const std::set<ui::EventType>& types() const { return types_; }
59
60 // ui::EventHandler:
OnEvent(ui::Event * event)61 void OnEvent(ui::Event* event) override {
62 if (types_.count(event->type()) > 0) {
63 std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(*event);
64 ui::Event::DispatcherApi(cloned_event.get()).set_target(event->target());
65 // The root location of located events should be in screen coordinates.
66 if (cloned_event->IsLocatedEvent() && cloned_event->target()) {
67 ui::LocatedEvent* located_event = cloned_event->AsLocatedEvent();
68 auto root = located_event->target()->GetScreenLocationF(*located_event);
69 located_event->set_root_location_f(root);
70 }
71 observer_->OnEvent(*cloned_event);
72 }
73 }
74
75 private:
76 ui::EventObserver* observer_;
77 ui::EventTarget* target_;
78 const std::set<ui::EventType> types_;
79
80 DISALLOW_COPY_AND_ASSIGN(EventObserverAdapter);
81 };
82
83 ////////////////////////////////////////////////////////////////////////////////
84 // Env, public:
85
~Env()86 Env::~Env() {
87 for (EnvObserver& observer : observers_)
88 observer.OnWillDestroyEnv();
89
90 if (this == g_primary_instance)
91 g_primary_instance = nullptr;
92 }
93
94 // static
CreateInstance()95 std::unique_ptr<Env> Env::CreateInstance() {
96 DCHECK(!g_primary_instance);
97 // No make_unique as constructor is private.
98 std::unique_ptr<Env> env(new Env());
99 g_primary_instance = env.get();
100 env->Init();
101 return env;
102 }
103
104 // static
GetInstance()105 Env* Env::GetInstance() {
106 Env* env = g_primary_instance;
107 DCHECK(env) << "Env::CreateInstance must be called before getting the "
108 "instance of Env.";
109 return env;
110 }
111
112 // static
HasInstance()113 bool Env::HasInstance() {
114 return !!g_primary_instance;
115 }
116
AddObserver(EnvObserver * observer)117 void Env::AddObserver(EnvObserver* observer) {
118 observers_.AddObserver(observer);
119 }
120
RemoveObserver(EnvObserver * observer)121 void Env::RemoveObserver(EnvObserver* observer) {
122 observers_.RemoveObserver(observer);
123 }
124
AddWindowEventDispatcherObserver(WindowEventDispatcherObserver * observer)125 void Env::AddWindowEventDispatcherObserver(
126 WindowEventDispatcherObserver* observer) {
127 window_event_dispatcher_observers_.AddObserver(observer);
128 }
129
RemoveWindowEventDispatcherObserver(WindowEventDispatcherObserver * observer)130 void Env::RemoveWindowEventDispatcherObserver(
131 WindowEventDispatcherObserver* observer) {
132 window_event_dispatcher_observers_.RemoveObserver(observer);
133 }
134
IsMouseButtonDown() const135 bool Env::IsMouseButtonDown() const {
136 return input_state_lookup_.get() ? input_state_lookup_->IsMouseButtonDown() :
137 mouse_button_flags_ != 0;
138 }
139
SetLastMouseLocation(const gfx::Point & last_mouse_location)140 void Env::SetLastMouseLocation(const gfx::Point& last_mouse_location) {
141 last_mouse_location_ = last_mouse_location;
142 }
143
SetGestureRecognizer(std::unique_ptr<ui::GestureRecognizer> gesture_recognizer)144 void Env::SetGestureRecognizer(
145 std::unique_ptr<ui::GestureRecognizer> gesture_recognizer) {
146 gesture_recognizer_ = std::move(gesture_recognizer);
147 }
148
GetWindowOcclusionTracker()149 WindowOcclusionTracker* Env::GetWindowOcclusionTracker() {
150 if (!window_occlusion_tracker_) {
151 // Use base::WrapUnique + new because of the constructor is private.
152 window_occlusion_tracker_ = base::WrapUnique(new WindowOcclusionTracker());
153 }
154
155 return window_occlusion_tracker_.get();
156 }
157
PauseWindowOcclusionTracking()158 void Env::PauseWindowOcclusionTracking() {
159 const bool was_paused = GetWindowOcclusionTracker();
160 GetWindowOcclusionTracker()->Pause();
161 if (!was_paused) {
162 for (EnvObserver& observer : observers_)
163 observer.OnWindowOcclusionTrackingPaused();
164 }
165 }
166
UnpauseWindowOcclusionTracking()167 void Env::UnpauseWindowOcclusionTracking() {
168 GetWindowOcclusionTracker()->Unpause();
169 if (!GetWindowOcclusionTracker()->IsPaused()) {
170 for (EnvObserver& observer : observers_)
171 observer.OnWindowOcclusionTrackingResumed();
172 }
173 }
174
AddEventObserver(ui::EventObserver * observer,ui::EventTarget * target,const std::set<ui::EventType> & types)175 void Env::AddEventObserver(ui::EventObserver* observer,
176 ui::EventTarget* target,
177 const std::set<ui::EventType>& types) {
178 DCHECK(!types.empty()) << "Observers must observe at least one event type";
179 auto adapter(std::make_unique<EventObserverAdapter>(observer, target, types));
180 event_observer_adapter_list_.AddObserver(adapter.get());
181 event_observer_adapters_.insert(std::move(adapter));
182 }
183
RemoveEventObserver(ui::EventObserver * observer)184 void Env::RemoveEventObserver(ui::EventObserver* observer) {
185 for (auto& adapter : event_observer_adapters_) {
186 if (adapter->observer() == observer) {
187 event_observer_adapter_list_.RemoveObserver(adapter.get());
188 event_observer_adapters_.erase(adapter);
189 return;
190 }
191 }
192 }
193
NotifyEventObservers(const ui::Event & event)194 void Env::NotifyEventObservers(const ui::Event& event) {
195 for (auto& adapter : event_observer_adapter_list_) {
196 if (adapter.types().count(event.type()) > 0 &&
197 (adapter.target() == event.target() || adapter.target() == this)) {
198 adapter.observer()->OnEvent(event);
199 }
200 }
201 }
202
203 ////////////////////////////////////////////////////////////////////////////////
204 // Env, private:
205
206 // static
207 bool Env::initial_throttle_input_on_resize_ = true;
208
Env()209 Env::Env()
210 : env_controller_(std::make_unique<EnvInputStateController>(this)),
211 gesture_recognizer_(std::make_unique<ui::GestureRecognizerImpl>()),
212 input_state_lookup_(InputStateLookup::Create()) {
213 #if defined(USE_X11)
214 // In Ozone/X11, the cursor factory is initialized by the platform
215 // initialization code.
216 if (!features::IsUsingOzonePlatform() &&
217 !base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless))
218 cursor_factory_ = std::make_unique<ui::X11CursorFactory>();
219 #endif
220 }
221
Init()222 void Env::Init() {
223 #if defined(USE_OZONE)
224 // The ozone platform can provide its own event source. So initialize the
225 // platform before creating the default event source. If running inside mus
226 // let the mus process initialize ozone instead.
227 if (features::IsUsingOzonePlatform()) {
228 ui::OzonePlatform::InitParams params;
229 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
230 // TODO(kylechar): Pass in single process information to
231 // Env::CreateInstance() instead of checking flags here.
232 params.single_process = command_line->HasSwitch("single-process") ||
233 command_line->HasSwitch("in-process-gpu");
234 ui::OzonePlatform::InitializeForUI(params);
235 }
236 #endif
237 if (!ui::PlatformEventSource::GetInstance())
238 event_source_ = ui::PlatformEventSource::CreateDefault();
239 }
240
NotifyWindowInitialized(Window * window)241 void Env::NotifyWindowInitialized(Window* window) {
242 for (EnvObserver& observer : observers_)
243 observer.OnWindowInitialized(window);
244 }
245
NotifyHostInitialized(WindowTreeHost * host)246 void Env::NotifyHostInitialized(WindowTreeHost* host) {
247 for (EnvObserver& observer : observers_)
248 observer.OnHostInitialized(host);
249 }
250
251 ////////////////////////////////////////////////////////////////////////////////
252 // Env, ui::EventTarget implementation:
253
CanAcceptEvent(const ui::Event & event)254 bool Env::CanAcceptEvent(const ui::Event& event) {
255 return true;
256 }
257
GetParentTarget()258 ui::EventTarget* Env::GetParentTarget() {
259 return nullptr;
260 }
261
GetChildIterator() const262 std::unique_ptr<ui::EventTargetIterator> Env::GetChildIterator() const {
263 return nullptr;
264 }
265
GetEventTargeter()266 ui::EventTargeter* Env::GetEventTargeter() {
267 NOTREACHED();
268 return nullptr;
269 }
270
271 } // namespace aura
272