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