Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: services/window_manager/window_manager_root.cc

Issue 1530333005: Delete the ViewManager and WindowManager services. (Closed) Base URL: git@github.com:domokit/mojo.git@cl-2c
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "services/window_manager/window_manager_root.h"
6
7 #include <algorithm>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/stl_util.h"
13 #include "mojo/converters/geometry/geometry_type_converters.h"
14 #include "mojo/converters/input_events/input_events_type_converters.h"
15 #include "mojo/public/cpp/application/application_connection.h"
16 #include "mojo/public/cpp/application/application_impl.h"
17 #include "mojo/public/interfaces/application/shell.mojom.h"
18 #include "mojo/services/view_manager/cpp/view.h"
19 #include "mojo/services/view_manager/cpp/view_manager.h"
20 #include "services/window_manager/capture_controller.h"
21 #include "services/window_manager/focus_controller.h"
22 #include "services/window_manager/focus_rules.h"
23 #include "services/window_manager/hit_test.h"
24 #include "services/window_manager/view_event_dispatcher.h"
25 #include "services/window_manager/view_target.h"
26 #include "services/window_manager/view_targeter.h"
27 #include "services/window_manager/window_manager_delegate.h"
28
29 using mojo::ApplicationConnection;
30 using mojo::Id;
31 using mojo::ServiceProvider;
32 using mojo::View;
33 using mojo::WindowManager;
34
35 namespace window_manager {
36
37 namespace {
38
39 Id GetIdForView(View* view) {
40 return view ? view->id() : 0;
41 }
42
43 } // namespace
44
45 // Used for calls to Embed() that occur before we've connected to the
46 // ViewManager.
47 struct WindowManagerRoot::PendingEmbed {
48 mojo::String url;
49 mojo::InterfaceRequest<ServiceProvider> services;
50 mojo::ServiceProviderPtr exposed_services;
51 };
52
53 ////////////////////////////////////////////////////////////////////////////////
54 // WindowManagerRoot, public:
55
56 WindowManagerRoot::WindowManagerRoot(
57 mojo::ApplicationImpl* application_impl,
58 mojo::ApplicationConnection* connection,
59 WindowManagerControllerFactory* controller_factory,
60 mojo::InterfaceRequest<mojo::WindowManager> request)
61 : application_impl_(application_impl),
62 connection_(connection),
63 root_(nullptr) {
64 window_manager_controller_ =
65 controller_factory->CreateWindowManagerController(connection, this);
66 LaunchViewManager(application_impl_);
67
68 // We own WindowManagerImpl. When binding to the request, WindowManagerImpl
69 // registers an error callback to WindowManagerRoot::RemoveConnectedService,
70 // which will delete it.
71 AddConnectedService(make_scoped_ptr(
72 new WindowManagerImpl(this, request.PassMessagePipe(), false)));
73 }
74
75 WindowManagerRoot::~WindowManagerRoot() {
76 // TODO(msw|sky): Should this destructor explicitly delete the ViewManager?
77 mojo::ViewManager* cached_view_manager = view_manager();
78 for (RegisteredViewIdSet::const_iterator it = registered_view_id_set_.begin();
79 cached_view_manager && it != registered_view_id_set_.end(); ++it) {
80 View* view = cached_view_manager->GetViewById(*it);
81 if (view && view == root_)
82 root_ = nullptr;
83 if (view)
84 view->RemoveObserver(this);
85 }
86 registered_view_id_set_.clear();
87 DCHECK(!root_);
88
89 // connected_services_ destructor will ensure we don't leak any
90 // WindowManagerImpl objects and close all connections.
91 }
92
93 void WindowManagerRoot::AddConnectedService(
94 scoped_ptr<WindowManagerImpl> connection) {
95 connected_services_.push_back(connection.Pass());
96 }
97
98 void WindowManagerRoot::RemoveConnectedService(WindowManagerImpl* connection) {
99 ConnectedServices::iterator position = std::find(
100 connected_services_.begin(), connected_services_.end(), connection);
101 DCHECK(position != connected_services_.end());
102
103 connected_services_.erase(position);
104
105 // Having no inbound connection is not a guarantee we are no longer used: we
106 // can be processing an embed request (App 1 asked for a WindowManager, calls
107 // Embed then immediately closes the connection, EmbeddedApp is not yet
108 // started).
109 }
110
111 bool WindowManagerRoot::SetCapture(Id view_id) {
112 View* view = view_manager()->GetViewById(view_id);
113 return view && SetCaptureImpl(view);
114 }
115
116 bool WindowManagerRoot::FocusWindow(Id view_id) {
117 View* view = view_manager()->GetViewById(view_id);
118 return view && FocusWindowImpl(view);
119 }
120
121 bool WindowManagerRoot::ActivateWindow(Id view_id) {
122 View* view = view_manager()->GetViewById(view_id);
123 return view && ActivateWindowImpl(view);
124 }
125
126 bool WindowManagerRoot::IsReady() const {
127 return root_;
128 }
129
130 void WindowManagerRoot::InitFocus(scoped_ptr<FocusRules> rules) {
131 DCHECK(root_);
132
133 focus_controller_.reset(new FocusController(rules.Pass()));
134 focus_controller_->AddObserver(this);
135 SetFocusController(root_, focus_controller_.get());
136
137 capture_controller_.reset(new CaptureController);
138 capture_controller_->AddObserver(this);
139 SetCaptureController(root_, capture_controller_.get());
140 }
141
142 void WindowManagerRoot::Embed(
143 const mojo::String& url,
144 mojo::InterfaceRequest<mojo::ServiceProvider> services,
145 mojo::ServiceProviderPtr exposed_services) {
146 if (view_manager()) {
147 window_manager_controller_->Embed(url, services.Pass(),
148 exposed_services.Pass());
149 return;
150 }
151 scoped_ptr<PendingEmbed> pending_embed(new PendingEmbed);
152 pending_embed->url = url;
153 pending_embed->services = services.Pass();
154 pending_embed->exposed_services = exposed_services.Pass();
155 pending_embeds_.push_back(pending_embed.release());
156 }
157
158 ////////////////////////////////////////////////////////////////////////////////
159 // WindowManagerRoot, ViewManagerDelegate implementation:
160
161 void WindowManagerRoot::OnEmbed(
162 View* root,
163 mojo::InterfaceRequest<mojo::ServiceProvider> services,
164 mojo::ServiceProviderPtr exposed_services) {
165 DCHECK(!root_);
166 root_ = root;
167
168 view_event_dispatcher_.reset(new ViewEventDispatcher);
169
170 RegisterSubtree(root_);
171
172 if (window_manager_controller_.get()) {
173 window_manager_controller_->OnEmbed(root, services.Pass(),
174 exposed_services.Pass());
175 }
176
177 for (PendingEmbed* pending_embed : pending_embeds_) {
178 Embed(pending_embed->url, pending_embed->services.Pass(),
179 pending_embed->exposed_services.Pass());
180 }
181 pending_embeds_.clear();
182 }
183
184 void WindowManagerRoot::OnViewManagerDisconnected(
185 mojo::ViewManager* view_manager) {
186 if (window_manager_controller_.get())
187 window_manager_controller_->OnViewManagerDisconnected(view_manager);
188 delete this;
189 }
190
191 bool WindowManagerRoot::OnPerformAction(mojo::View* view,
192 const std::string& action) {
193 if (!view)
194 return false;
195 if (action == "capture")
196 return SetCaptureImpl(view);
197 if (action == "focus")
198 return FocusWindowImpl(view);
199 else if (action == "activate")
200 return ActivateWindowImpl(view);
201 return false;
202 }
203
204 ////////////////////////////////////////////////////////////////////////////////
205 // WindowManagerRoot, ViewObserver implementation:
206
207 void WindowManagerRoot::OnTreeChanged(
208 const ViewObserver::TreeChangeParams& params) {
209 if (params.receiver != root_)
210 return;
211 DCHECK(params.old_parent || params.new_parent);
212 if (!params.target)
213 return;
214
215 if (params.new_parent) {
216 if (registered_view_id_set_.find(params.target->id()) ==
217 registered_view_id_set_.end()) {
218 RegisteredViewIdSet::const_iterator it =
219 registered_view_id_set_.find(params.new_parent->id());
220 DCHECK(it != registered_view_id_set_.end());
221 RegisterSubtree(params.target);
222 }
223 } else if (params.old_parent) {
224 UnregisterSubtree(params.target);
225 }
226 }
227
228 void WindowManagerRoot::OnViewDestroying(View* view) {
229 Unregister(view);
230 if (view == root_) {
231 root_ = nullptr;
232 if (focus_controller_)
233 focus_controller_->RemoveObserver(this);
234 if (capture_controller_)
235 capture_controller_->RemoveObserver(this);
236 }
237 }
238
239 ////////////////////////////////////////////////////////////////////////////////
240 // WindowManagerRoot, ui::EventHandler implementation:
241
242 void WindowManagerRoot::OnEvent(ui::Event* event) {
243 if (!window_manager_client_)
244 return;
245
246 View* view = static_cast<ViewTarget*>(event->target())->view();
247 if (!view)
248 return;
249
250 if (event->IsKeyEvent()) {
251 const ui::KeyEvent* key_event = static_cast<const ui::KeyEvent*>(event);
252 if (key_event->type() == ui::ET_KEY_PRESSED) {
253 ui::Accelerator accelerator = ConvertEventToAccelerator(key_event);
254 if (accelerator_manager_.Process(accelerator, view))
255 return;
256 }
257 }
258
259 if (focus_controller_)
260 focus_controller_->OnEvent(event);
261
262 window_manager_client_->DispatchInputEventToView(view->id(),
263 mojo::Event::From(*event));
264 }
265
266 ////////////////////////////////////////////////////////////////////////////////
267 // WindowManagerRoot, mojo::FocusControllerObserver implementation:
268
269 void WindowManagerRoot::OnFocused(View* gained_focus) {
270 for (ConnectedServices::const_iterator it = connected_services_.begin();
271 it != connected_services_.end(); ++it) {
272 (*it)->NotifyViewFocused(GetIdForView(gained_focus));
273 }
274 }
275
276 void WindowManagerRoot::OnActivated(View* gained_active) {
277 for (ConnectedServices::const_iterator it = connected_services_.begin();
278 it != connected_services_.end(); ++it) {
279 (*it)->NotifyWindowActivated(GetIdForView(gained_active));
280 }
281 if (gained_active)
282 gained_active->MoveToFront();
283 }
284
285 ////////////////////////////////////////////////////////////////////////////////
286 // WindowManagerRoot, mojo::CaptureControllerObserver implementation:
287
288 void WindowManagerRoot::OnCaptureChanged(View* gained_capture) {
289 for (ConnectedServices::const_iterator it = connected_services_.begin();
290 it != connected_services_.end(); ++it) {
291 (*it)->NotifyCaptureChanged(GetIdForView(gained_capture));
292 }
293 if (gained_capture)
294 gained_capture->MoveToFront();
295 }
296
297 ////////////////////////////////////////////////////////////////////////////////
298 // WindowManagerRoot, private:
299
300 bool WindowManagerRoot::SetCaptureImpl(View* view) {
301 CHECK(view);
302 capture_controller_->SetCapture(view);
303 return capture_controller_->GetCapture() == view;
304 }
305
306 bool WindowManagerRoot::FocusWindowImpl(View* view) {
307 CHECK(view);
308 focus_controller_->FocusView(view);
309 return focus_controller_->GetFocusedView() == view;
310 }
311
312 bool WindowManagerRoot::ActivateWindowImpl(View* view) {
313 CHECK(view);
314 focus_controller_->ActivateView(view);
315 return focus_controller_->GetActiveView() == view;
316 }
317
318 void WindowManagerRoot::RegisterSubtree(View* view) {
319 view->AddObserver(this);
320 DCHECK(registered_view_id_set_.find(view->id()) ==
321 registered_view_id_set_.end());
322 // All events pass through the root during dispatch, so we only need a handler
323 // installed there.
324 if (view == root_) {
325 ViewTarget* target = ViewTarget::TargetFromView(view);
326 target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter()));
327 target->AddPreTargetHandler(this);
328 view_event_dispatcher_->SetRootViewTarget(target);
329 }
330 registered_view_id_set_.insert(view->id());
331 View::Children::const_iterator it = view->children().begin();
332 for (; it != view->children().end(); ++it)
333 RegisterSubtree(*it);
334 }
335
336 void WindowManagerRoot::UnregisterSubtree(View* view) {
337 for (View* child : view->children())
338 UnregisterSubtree(child);
339 Unregister(view);
340 }
341
342 void WindowManagerRoot::Unregister(View* view) {
343 RegisteredViewIdSet::iterator it = registered_view_id_set_.find(view->id());
344 if (it == registered_view_id_set_.end()) {
345 // Because we unregister in OnViewDestroying() we can still get a subsequent
346 // OnTreeChanged for the same view. Ignore this one.
347 return;
348 }
349 view->RemoveObserver(this);
350 DCHECK(it != registered_view_id_set_.end());
351 registered_view_id_set_.erase(it);
352 }
353
354 void WindowManagerRoot::DispatchInputEventToView(View* view,
355 mojo::EventPtr event) {
356 window_manager_client_->DispatchInputEventToView(view->id(), event.Pass());
357 }
358
359 void WindowManagerRoot::SetViewportSize(const gfx::Size& size) {
360 window_manager_client_->SetViewportSize(mojo::Size::From(size));
361 }
362
363 void WindowManagerRoot::LaunchViewManager(mojo::ApplicationImpl* app) {
364 // TODO(sky): figure out logic if this connection goes away.
365 view_manager_client_factory_.reset(
366 new mojo::ViewManagerClientFactory(application_impl_->shell(), this));
367
368 ApplicationConnection* view_manager_app =
369 app->ConnectToApplication("mojo:view_manager");
370 view_manager_app->ConnectToService(&view_manager_service_);
371
372 view_manager_app->AddService<WindowManagerInternal>(this);
373 view_manager_app->AddService<mojo::NativeViewportEventDispatcher>(this);
374
375 view_manager_app->ConnectToService(&window_manager_client_);
376 }
377
378 void WindowManagerRoot::Create(
379 ApplicationConnection* connection,
380 mojo::InterfaceRequest<WindowManagerInternal> request) {
381 if (wm_internal_binding_.get()) {
382 VLOG(1)
383 << "WindowManager allows only one WindowManagerInternal connection.";
384 return;
385 }
386 wm_internal_binding_.reset(
387 new mojo::Binding<WindowManagerInternal>(this, request.Pass()));
388 }
389
390 void WindowManagerRoot::Create(
391 mojo::ApplicationConnection* connection,
392 mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> request) {
393 new NativeViewportEventDispatcherImpl(this, request.Pass());
394 }
395
396 void WindowManagerRoot::CreateWindowManagerForViewManagerClient(
397 uint16_t connection_id,
398 mojo::ScopedMessagePipeHandle window_manager_pipe) {
399 // TODO(sky): pass in |connection_id| for validation.
400 AddConnectedService(make_scoped_ptr(
401 new WindowManagerImpl(this, window_manager_pipe.Pass(), true)));
402 }
403
404 void WindowManagerRoot::SetViewManagerClient(
405 mojo::ScopedMessagePipeHandle view_manager_client_request) {
406 view_manager_client_.reset(
407 mojo::ViewManagerClientFactory::WeakBindViewManagerToPipe(
408 mojo::MakeRequest<mojo::ViewManagerClient>(
409 view_manager_client_request.Pass()),
410 view_manager_service_.Pass(), application_impl_->shell(), this));
411 }
412
413 } // namespace window_manager
OLDNEW
« no previous file with comments | « services/window_manager/window_manager_root.h ('k') | services/window_manager/window_manager_root_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698