OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "mojo/services/window_manager/window_manager_app.h" | |
6 | |
7 #include "base/message_loop/message_loop.h" | |
8 #include "base/stl_util.h" | |
9 #include "mojo/converters/geometry/geometry_type_converters.h" | |
10 #include "mojo/converters/input_events/input_events_type_converters.h" | |
11 #include "mojo/public/cpp/application/application_connection.h" | |
12 #include "mojo/public/cpp/application/application_impl.h" | |
13 #include "mojo/public/interfaces/application/shell.mojom.h" | |
14 #include "mojo/services/public/cpp/view_manager/view.h" | |
15 #include "mojo/services/public/cpp/view_manager/view_manager.h" | |
16 #include "mojo/services/window_manager/focus_controller.h" | |
17 #include "mojo/services/window_manager/focus_rules.h" | |
18 #include "mojo/services/window_manager/view_event_dispatcher.h" | |
19 #include "mojo/services/window_manager/view_target.h" | |
20 #include "mojo/services/window_manager/view_targeter.h" | |
21 #include "mojo/services/window_manager/window_manager_delegate.h" | |
22 #include "ui/base/hit_test.h" | |
23 | |
24 namespace mojo { | |
25 | |
26 namespace { | |
27 | |
28 Id GetIdForView(View* view) { | |
29 return view ? view->id() : 0; | |
30 } | |
31 | |
32 } // namespace | |
33 | |
34 // Used for calls to Embed() that occur before we've connected to the | |
35 // ViewManager. | |
36 struct WindowManagerApp::PendingEmbed { | |
37 String url; | |
38 InterfaceRequest<mojo::ServiceProvider> service_provider; | |
39 }; | |
40 | |
41 //////////////////////////////////////////////////////////////////////////////// | |
42 // WindowManagerApp, public: | |
43 | |
44 WindowManagerApp::WindowManagerApp( | |
45 ViewManagerDelegate* view_manager_delegate, | |
46 WindowManagerDelegate* window_manager_delegate) | |
47 : shell_(nullptr), | |
48 native_viewport_event_dispatcher_factory_(this), | |
49 wrapped_view_manager_delegate_(view_manager_delegate), | |
50 window_manager_delegate_(window_manager_delegate), | |
51 view_manager_(nullptr), | |
52 root_(nullptr) { | |
53 } | |
54 | |
55 WindowManagerApp::~WindowManagerApp() { | |
56 STLDeleteElements(&connections_); | |
57 } | |
58 | |
59 void WindowManagerApp::AddConnection(WindowManagerImpl* connection) { | |
60 DCHECK(connections_.find(connection) == connections_.end()); | |
61 connections_.insert(connection); | |
62 } | |
63 | |
64 void WindowManagerApp::RemoveConnection(WindowManagerImpl* connection) { | |
65 DCHECK(connections_.find(connection) != connections_.end()); | |
66 connections_.erase(connection); | |
67 } | |
68 | |
69 void WindowManagerApp::SetCapture(Id view) { | |
70 // TODO(erg): Capture. Another pile of worms that is mixed in here. | |
71 | |
72 // capture_client_->capture_client()->SetCapture(GetWindowForViewId(view)); | |
73 | |
74 // TODO(beng): notify connected clients that capture has changed, probably | |
75 // by implementing some capture-client observer. | |
76 } | |
77 | |
78 void WindowManagerApp::FocusWindow(Id view_id) { | |
79 View* view = view_manager_->GetViewById(view_id); | |
80 DCHECK(view); | |
81 focus_controller_->FocusView(view); | |
82 } | |
83 | |
84 void WindowManagerApp::ActivateWindow(Id view_id) { | |
85 View* view = view_manager_->GetViewById(view_id); | |
86 DCHECK(view); | |
87 focus_controller_->ActivateView(view); | |
88 } | |
89 | |
90 bool WindowManagerApp::IsReady() const { | |
91 return view_manager_ && root_; | |
92 } | |
93 | |
94 void WindowManagerApp::InitFocus(scoped_ptr<mojo::FocusRules> rules) { | |
95 focus_controller_.reset(new mojo::FocusController(rules.Pass())); | |
96 focus_controller_->AddObserver(this); | |
97 | |
98 DCHECK(root_); | |
99 SetFocusController(root_, focus_controller_.get()); | |
100 } | |
101 | |
102 void WindowManagerApp::Embed( | |
103 const String& url, | |
104 InterfaceRequest<ServiceProvider> service_provider) { | |
105 if (view_manager_) { | |
106 window_manager_delegate_->Embed(url, service_provider.Pass()); | |
107 return; | |
108 } | |
109 scoped_ptr<PendingEmbed> pending_embed(new PendingEmbed); | |
110 pending_embed->url = url; | |
111 pending_embed->service_provider = service_provider.Pass(); | |
112 pending_embeds_.push_back(pending_embed.release()); | |
113 } | |
114 | |
115 //////////////////////////////////////////////////////////////////////////////// | |
116 // WindowManagerApp, ApplicationDelegate implementation: | |
117 | |
118 void WindowManagerApp::Initialize(ApplicationImpl* impl) { | |
119 shell_ = impl->shell(); | |
120 LaunchViewManager(impl); | |
121 } | |
122 | |
123 bool WindowManagerApp::ConfigureIncomingConnection( | |
124 ApplicationConnection* connection) { | |
125 connection->AddService(static_cast<InterfaceFactory<WindowManager>*>(this)); | |
126 return true; | |
127 } | |
128 | |
129 //////////////////////////////////////////////////////////////////////////////// | |
130 // WindowManagerApp, ViewManagerDelegate implementation: | |
131 | |
132 void WindowManagerApp::OnEmbed(ViewManager* view_manager, | |
133 View* root, | |
134 ServiceProviderImpl* exported_services, | |
135 scoped_ptr<ServiceProvider> imported_services) { | |
136 DCHECK(!view_manager_ && !root_); | |
137 view_manager_ = view_manager; | |
138 root_ = root; | |
139 | |
140 view_event_dispatcher_.reset(new ViewEventDispatcher()); | |
141 | |
142 RegisterSubtree(root_); | |
143 | |
144 // TODO(erg): Also move the capture client over. | |
145 // | |
146 // capture_client_.reset( | |
147 // new wm::ScopedCaptureClient(window_tree_host_->window())); | |
148 | |
149 if (wrapped_view_manager_delegate_) { | |
150 wrapped_view_manager_delegate_->OnEmbed( | |
151 view_manager, root, exported_services, imported_services.Pass()); | |
152 } | |
153 | |
154 for (PendingEmbed* pending_embed : pending_embeds_) | |
155 Embed(pending_embed->url, pending_embed->service_provider.Pass()); | |
156 pending_embeds_.clear(); | |
157 } | |
158 | |
159 void WindowManagerApp::OnViewManagerDisconnected( | |
160 ViewManager* view_manager) { | |
161 DCHECK_EQ(view_manager_, view_manager); | |
162 if (wrapped_view_manager_delegate_) | |
163 wrapped_view_manager_delegate_->OnViewManagerDisconnected(view_manager); | |
164 view_manager_ = nullptr; | |
165 base::MessageLoop::current()->Quit(); | |
166 } | |
167 | |
168 //////////////////////////////////////////////////////////////////////////////// | |
169 // WindowManagerApp, ViewObserver implementation: | |
170 | |
171 void WindowManagerApp::OnTreeChanged( | |
172 const ViewObserver::TreeChangeParams& params) { | |
173 if (params.receiver != root_) | |
174 return; | |
175 DCHECK(params.old_parent || params.new_parent); | |
176 if (!params.target) | |
177 return; | |
178 | |
179 if (params.new_parent) { | |
180 if (registered_view_id_set_.find(params.target->id()) == | |
181 registered_view_id_set_.end()) { | |
182 RegisteredViewIdSet::const_iterator it = | |
183 registered_view_id_set_.find(params.new_parent->id()); | |
184 DCHECK(it != registered_view_id_set_.end()); | |
185 RegisterSubtree(params.target); | |
186 } | |
187 } else if (params.old_parent) { | |
188 UnregisterSubtree(params.target); | |
189 } | |
190 } | |
191 | |
192 void WindowManagerApp::OnViewDestroying(View* view) { | |
193 if (view != root_) { | |
194 Unregister(view); | |
195 return; | |
196 } | |
197 root_ = nullptr; | |
198 if (focus_controller_) | |
199 focus_controller_->RemoveObserver(this); | |
200 } | |
201 | |
202 //////////////////////////////////////////////////////////////////////////////// | |
203 // WindowManagerApp, ui::EventHandler implementation: | |
204 | |
205 void WindowManagerApp::OnEvent(ui::Event* event) { | |
206 if (!window_manager_client_) | |
207 return; | |
208 | |
209 View* view = static_cast<ViewTarget*>(event->target())->view(); | |
210 if (!view) | |
211 return; | |
212 | |
213 if (focus_controller_) | |
214 focus_controller_->OnEvent(event); | |
215 | |
216 window_manager_client_->DispatchInputEventToView(view->id(), | |
217 Event::From(*event)); | |
218 } | |
219 | |
220 //////////////////////////////////////////////////////////////////////////////// | |
221 // WindowManagerApp, mojo::FocusControllerObserver implementation: | |
222 | |
223 void WindowManagerApp::OnViewFocused(View* gained_focus, | |
224 View* lost_focus) { | |
225 for (Connections::const_iterator it = connections_.begin(); | |
226 it != connections_.end(); ++it) { | |
227 (*it)->NotifyViewFocused(GetIdForView(gained_focus), | |
228 GetIdForView(lost_focus)); | |
229 } | |
230 } | |
231 | |
232 void WindowManagerApp::OnViewActivated(View* gained_active, | |
233 View* lost_active) { | |
234 for (Connections::const_iterator it = connections_.begin(); | |
235 it != connections_.end(); ++it) { | |
236 (*it)->NotifyWindowActivated(GetIdForView(gained_active), | |
237 GetIdForView(lost_active)); | |
238 } | |
239 if (gained_active) | |
240 gained_active->MoveToFront(); | |
241 } | |
242 | |
243 //////////////////////////////////////////////////////////////////////////////// | |
244 // WindowManagerApp, private: | |
245 | |
246 void WindowManagerApp::RegisterSubtree(View* view) { | |
247 view->AddObserver(this); | |
248 DCHECK(registered_view_id_set_.find(view->id()) == | |
249 registered_view_id_set_.end()); | |
250 // All events pass through the root during dispatch, so we only need a handler | |
251 // installed there. | |
252 if (view == root_) { | |
253 ViewTarget* target = ViewTarget::TargetFromView(view); | |
254 target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); | |
255 target->AddPreTargetHandler(this); | |
256 view_event_dispatcher_->SetRootViewTarget(target); | |
257 } | |
258 registered_view_id_set_.insert(view->id()); | |
259 View::Children::const_iterator it = view->children().begin(); | |
260 for (; it != view->children().end(); ++it) | |
261 RegisterSubtree(*it); | |
262 } | |
263 | |
264 void WindowManagerApp::UnregisterSubtree(View* view) { | |
265 for (View* child : view->children()) | |
266 UnregisterSubtree(child); | |
267 Unregister(view); | |
268 } | |
269 | |
270 void WindowManagerApp::Unregister(View* view) { | |
271 RegisteredViewIdSet::iterator it = registered_view_id_set_.find(view->id()); | |
272 if (it == registered_view_id_set_.end()) { | |
273 // Because we unregister in OnViewDestroying() we can still get a subsequent | |
274 // OnTreeChanged for the same view. Ignore this one. | |
275 return; | |
276 } | |
277 view->RemoveObserver(this); | |
278 DCHECK(it != registered_view_id_set_.end()); | |
279 registered_view_id_set_.erase(it); | |
280 } | |
281 | |
282 void WindowManagerApp::DispatchInputEventToView(View* view, EventPtr event) { | |
283 window_manager_client_->DispatchInputEventToView(view->id(), event.Pass()); | |
284 } | |
285 | |
286 void WindowManagerApp::SetViewportSize(const gfx::Size& size) { | |
287 window_manager_client_->SetViewportSize(Size::From(size)); | |
288 } | |
289 | |
290 void WindowManagerApp::LaunchViewManager(ApplicationImpl* app) { | |
291 // TODO(sky): figure out logic if this connection goes away. | |
292 view_manager_client_factory_.reset( | |
293 new ViewManagerClientFactory(shell_, this)); | |
294 | |
295 MessagePipe pipe; | |
296 ApplicationConnection* view_manager_app = | |
297 app->ConnectToApplication("mojo:view_manager"); | |
298 ServiceProvider* view_manager_service_provider = | |
299 view_manager_app->GetServiceProvider(); | |
300 view_manager_service_provider->ConnectToService(ViewManagerService::Name_, | |
301 pipe.handle1.Pass()); | |
302 view_manager_client_ = ViewManagerClientFactory::WeakBindViewManagerToPipe( | |
303 pipe.handle0.Pass(), shell_, this).Pass(); | |
304 | |
305 view_manager_app->AddService(&native_viewport_event_dispatcher_factory_); | |
306 view_manager_app->AddService( | |
307 static_cast<InterfaceFactory<WindowManagerInternal>*>(this)); | |
308 | |
309 view_manager_app->ConnectToService(&window_manager_client_); | |
310 } | |
311 | |
312 void WindowManagerApp::Create(ApplicationConnection* connection, | |
313 InterfaceRequest<WindowManagerInternal> request) { | |
314 if (wm_internal_binding_.get()) { | |
315 VLOG(1) << | |
316 "WindowManager allows only one WindowManagerInternal connection."; | |
317 return; | |
318 } | |
319 wm_internal_binding_.reset( | |
320 new Binding<WindowManagerInternal>(this, request.Pass())); | |
321 } | |
322 | |
323 void WindowManagerApp::Create(ApplicationConnection* connection, | |
324 InterfaceRequest<WindowManager> request) { | |
325 WindowManagerImpl* wm = new WindowManagerImpl(this, false); | |
326 wm->Bind(request.PassMessagePipe()); | |
327 // WindowManagerImpl is deleted when the connection has an error, or from our | |
328 // destructor. | |
329 } | |
330 | |
331 void WindowManagerApp::CreateWindowManagerForViewManagerClient( | |
332 uint16_t connection_id, | |
333 ScopedMessagePipeHandle window_manager_pipe) { | |
334 WindowManagerImpl* wm = new WindowManagerImpl(this, true); | |
335 wm->Bind(window_manager_pipe.Pass()); | |
336 // WindowManagerImpl is deleted when the connection has an error, or from our | |
337 // destructor. | |
338 } | |
339 | |
340 } // namespace mojo | |
OLD | NEW |