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

Side by Side Diff: mojo/services/window_manager/window_manager_app.cc

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

Powered by Google App Engine
This is Rietveld 408576698