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

Side by Side Diff: mojo/services/view_manager/cpp/lib/view_manager_client_impl.cc

Issue 1531403003: Delete the ViewManager and WindowManager services. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-3
Patch Set: rebase Created 4 years, 11 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 "view_manager/cpp/lib/view_manager_client_impl.h"
6
7 #include "mojo/public/cpp/application/application_impl.h"
8 #include "mojo/public/cpp/application/connect.h"
9 #include "mojo/public/cpp/application/service_provider_impl.h"
10 #include "mojo/public/interfaces/application/service_provider.mojom.h"
11 #include "mojo/public/interfaces/application/shell.mojom.h"
12 #include "view_manager/cpp/lib/view_private.h"
13 #include "view_manager/cpp/util.h"
14 #include "view_manager/cpp/view_manager_delegate.h"
15 #include "view_manager/cpp/view_observer.h"
16
17 namespace mojo {
18
19 Id MakeTransportId(ConnectionSpecificId connection_id,
20 ConnectionSpecificId local_id) {
21 return (connection_id << 16) | local_id;
22 }
23
24 // Helper called to construct a local view object from transport data.
25 View* AddViewToViewManager(ViewManagerClientImpl* client,
26 View* parent,
27 const ViewDataPtr& view_data) {
28 // We don't use the ctor that takes a ViewManager here, since it will call
29 // back to the service and attempt to create a new view.
30 View* view = ViewPrivate::LocalCreate();
31 ViewPrivate private_view(view);
32 private_view.set_view_manager(client);
33 private_view.set_id(view_data->view_id);
34 private_view.set_visible(view_data->visible);
35 private_view.set_drawn(view_data->drawn);
36 private_view.LocalSetViewportMetrics(ViewportMetrics(),
37 *view_data->viewport_metrics);
38 private_view.set_properties(
39 view_data->properties.To<std::map<std::string, std::vector<uint8_t>>>());
40 client->AddView(view);
41 private_view.LocalSetBounds(Rect(), *view_data->bounds);
42 if (parent)
43 ViewPrivate(parent).LocalAddChild(view);
44 return view;
45 }
46
47 View* BuildViewTree(ViewManagerClientImpl* client,
48 const Array<ViewDataPtr>& views,
49 View* initial_parent) {
50 std::vector<View*> parents;
51 View* root = NULL;
52 View* last_view = NULL;
53 if (initial_parent)
54 parents.push_back(initial_parent);
55 for (size_t i = 0; i < views.size(); ++i) {
56 if (last_view && views[i]->parent_id == last_view->id()) {
57 parents.push_back(last_view);
58 } else if (!parents.empty()) {
59 while (parents.back()->id() != views[i]->parent_id)
60 parents.pop_back();
61 }
62 View* view = AddViewToViewManager(
63 client, !parents.empty() ? parents.back() : NULL, views[i]);
64 if (!last_view)
65 root = view;
66 last_view = view;
67 }
68 return root;
69 }
70
71 // Responsible for removing a root from the ViewManager when that view is
72 // destroyed.
73 class RootObserver : public ViewObserver {
74 public:
75 explicit RootObserver(View* root) : root_(root) {}
76 ~RootObserver() override {}
77
78 private:
79 // Overridden from ViewObserver:
80 void OnViewDestroyed(View* view) override {
81 DCHECK_EQ(view, root_);
82 static_cast<ViewManagerClientImpl*>(root_->view_manager())
83 ->RootDestroyed(root_);
84 view->RemoveObserver(this);
85 delete this;
86 }
87
88 View* root_;
89
90 MOJO_DISALLOW_COPY_AND_ASSIGN(RootObserver);
91 };
92
93 ViewManagerClientImpl::ViewManagerClientImpl(
94 ViewManagerDelegate* delegate,
95 Shell* shell,
96 InterfaceRequest<ViewManagerClient> request,
97 bool delete_on_error)
98 : connection_id_(0),
99 next_id_(1),
100 delegate_(delegate),
101 root_(nullptr),
102 capture_view_(nullptr),
103 focused_view_(nullptr),
104 activated_view_(nullptr),
105 wm_observer_binding_(this),
106 binding_(this, request.Pass()) {
107 if (delete_on_error)
108 binding_.set_connection_error_handler([this]() { delete this; });
109 }
110
111 ViewManagerClientImpl::~ViewManagerClientImpl() {
112 std::vector<View*> non_owned;
113 while (!views_.empty()) {
114 IdToViewMap::iterator it = views_.begin();
115 if (OwnsView(it->second->id())) {
116 it->second->Destroy();
117 } else {
118 non_owned.push_back(it->second);
119 views_.erase(it);
120 }
121 }
122 // Delete the non-owned views last. In the typical case these are roots. The
123 // exception is the window manager, which may know aboutother random views
124 // that it doesn't own.
125 // NOTE: we manually delete as we're a friend.
126 for (size_t i = 0; i < non_owned.size(); ++i)
127 delete non_owned[i];
128
129 delegate_->OnViewManagerDisconnected(this);
130 }
131
132 void ViewManagerClientImpl::DestroyView(Id view_id) {
133 DCHECK(service_);
134 service_->DeleteView(view_id, ActionCompletedCallback());
135 }
136
137 void ViewManagerClientImpl::AddChild(Id child_id, Id parent_id) {
138 DCHECK(service_);
139 service_->AddView(parent_id, child_id, ActionCompletedCallback());
140 }
141
142 void ViewManagerClientImpl::RemoveChild(Id child_id, Id parent_id) {
143 DCHECK(service_);
144 service_->RemoveViewFromParent(child_id, ActionCompletedCallback());
145 }
146
147 void ViewManagerClientImpl::Reorder(Id view_id,
148 Id relative_view_id,
149 OrderDirection direction) {
150 DCHECK(service_);
151 service_->ReorderView(view_id, relative_view_id, direction,
152 ActionCompletedCallback());
153 }
154
155 bool ViewManagerClientImpl::OwnsView(Id id) const {
156 return HiWord(id) == connection_id_;
157 }
158
159 void ViewManagerClientImpl::SetBounds(Id view_id, const Rect& bounds) {
160 DCHECK(service_);
161 service_->SetViewBounds(view_id, bounds.Clone(), ActionCompletedCallback());
162 }
163
164 void ViewManagerClientImpl::SetSurfaceId(Id view_id, SurfaceIdPtr surface_id) {
165 DCHECK(service_);
166 if (surface_id.is_null())
167 return;
168 service_->SetViewSurfaceId(view_id, surface_id.Pass(),
169 ActionCompletedCallback());
170 }
171
172 void ViewManagerClientImpl::SetFocus(Id view_id) {
173 // In order for us to get here we had to have exposed a view, which implies we
174 // got a connection.
175 DCHECK(service_);
176 service_->PerformAction(view_id, "focus", ActionCompletedCallback());
177 }
178
179 void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) {
180 DCHECK(service_);
181 service_->SetViewVisibility(view_id, visible, ActionCompletedCallback());
182 }
183
184 void ViewManagerClientImpl::SetProperty(Id view_id,
185 const std::string& name,
186 const std::vector<uint8_t>& data) {
187 DCHECK(service_);
188 service_->SetViewProperty(view_id, String(name), Array<uint8_t>::From(data),
189 ActionCompletedCallback());
190 }
191
192 void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
193 Embed(url, view_id, nullptr, nullptr);
194 }
195
196 void ViewManagerClientImpl::Embed(const String& url,
197 Id view_id,
198 InterfaceRequest<ServiceProvider> services,
199 ServiceProviderPtr exposed_services) {
200 DCHECK(service_);
201 service_->EmbedUrl(url, view_id, services.Pass(), exposed_services.Pass(),
202 ActionCompletedCallback());
203 }
204
205 void ViewManagerClientImpl::Embed(Id view_id, ViewManagerClientPtr client) {
206 DCHECK(service_);
207 service_->Embed(view_id, client.Pass(), ActionCompletedCallback());
208 }
209
210 void ViewManagerClientImpl::AddView(View* view) {
211 DCHECK(views_.find(view->id()) == views_.end());
212 views_[view->id()] = view;
213 }
214
215 void ViewManagerClientImpl::RemoveView(Id view_id) {
216 if (focused_view_ && focused_view_->id() == view_id)
217 OnFocusChanged(0);
218 if (capture_view_ && capture_view_->id() == view_id)
219 OnCaptureChanged(0);
220 if (activated_view_ && activated_view_->id() == view_id)
221 OnActiveWindowChanged(0);
222
223 IdToViewMap::iterator it = views_.find(view_id);
224 if (it != views_.end())
225 views_.erase(it);
226 }
227
228 void ViewManagerClientImpl::SetViewManagerService(
229 ViewManagerServicePtr service) {
230 DCHECK(!service_);
231 DCHECK(service);
232 service_ = service.Pass();
233 }
234 ////////////////////////////////////////////////////////////////////////////////
235 // ViewManagerClientImpl, ViewManager implementation:
236
237 Id ViewManagerClientImpl::CreateViewOnServer() {
238 DCHECK(service_);
239 const Id view_id = MakeTransportId(connection_id_, ++next_id_);
240 service_->CreateView(view_id, [this](ErrorCode code) {
241 OnActionCompleted(code == ErrorCode::NONE);
242 });
243 return view_id;
244 }
245
246 const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
247 return creator_url_;
248 }
249
250 View* ViewManagerClientImpl::GetRoot() {
251 return root_;
252 }
253
254 View* ViewManagerClientImpl::GetViewById(Id id) {
255 IdToViewMap::const_iterator it = views_.find(id);
256 return it != views_.end() ? it->second : NULL;
257 }
258
259 View* ViewManagerClientImpl::GetFocusedView() {
260 return focused_view_;
261 }
262
263 View* ViewManagerClientImpl::CreateView() {
264 View* view = new View(this, CreateViewOnServer());
265 AddView(view);
266 return view;
267 }
268
269 ////////////////////////////////////////////////////////////////////////////////
270 // ViewManagerClientImpl, ViewManagerClient implementation:
271
272 void ViewManagerClientImpl::OnEmbed(
273 ConnectionSpecificId connection_id,
274 const String& creator_url,
275 ViewDataPtr root_data,
276 ViewManagerServicePtr view_manager_service,
277 InterfaceRequest<ServiceProvider> services,
278 ServiceProviderPtr exposed_services,
279 ScopedMessagePipeHandle window_manager_pipe) {
280 if (view_manager_service) {
281 DCHECK(!service_);
282 service_ = view_manager_service.Pass();
283 }
284 connection_id_ = connection_id;
285 creator_url_ = String::From(creator_url);
286
287 DCHECK(!root_);
288 root_ = AddViewToViewManager(this, nullptr, root_data);
289 root_->AddObserver(new RootObserver(root_));
290
291 window_manager_.Bind(
292 InterfacePtrInfo<WindowManager>(window_manager_pipe.Pass(), 0u));
293 WindowManagerObserverPtr observer;
294 wm_observer_binding_.Bind(GetProxy(&observer));
295 // binding to |this| is safe here as |window_manager_| is bound to our
296 // lifetime.
297 window_manager_->GetFocusedAndActiveViews(
298 observer.Pass(),
299 [this](uint32_t capture_view_id, uint32_t focused_view_id,
300 uint32_t active_view_id) {
301 if (GetViewById(capture_view_id) != capture_view_)
302 OnCaptureChanged(capture_view_id);
303 if (GetViewById(focused_view_id) != focused_view_)
304 OnFocusChanged(focused_view_id);
305 if (GetViewById(active_view_id) != activated_view_)
306 OnActiveWindowChanged(active_view_id);
307 });
308
309 delegate_->OnEmbed(root_, services.Pass(), exposed_services.Pass());
310 }
311
312 void ViewManagerClientImpl::OnEmbeddedAppDisconnected(Id view_id) {
313 View* view = GetViewById(view_id);
314 if (view) {
315 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(),
316 OnViewEmbeddedAppDisconnected(view));
317 }
318 }
319
320 void ViewManagerClientImpl::OnViewBoundsChanged(Id view_id,
321 RectPtr old_bounds,
322 RectPtr new_bounds) {
323 View* view = GetViewById(view_id);
324 ViewPrivate(view).LocalSetBounds(*old_bounds, *new_bounds);
325 }
326
327 namespace {
328
329 void SetViewportMetricsOnDecendants(View* root,
330 const ViewportMetrics& old_metrics,
331 const ViewportMetrics& new_metrics) {
332 ViewPrivate(root).LocalSetViewportMetrics(old_metrics, new_metrics);
333 const View::Children& children = root->children();
334 for (size_t i = 0; i < children.size(); ++i)
335 SetViewportMetricsOnDecendants(children[i], old_metrics, new_metrics);
336 }
337 }
338
339 void ViewManagerClientImpl::OnViewViewportMetricsChanged(
340 ViewportMetricsPtr old_metrics,
341 ViewportMetricsPtr new_metrics) {
342 View* view = GetRoot();
343 if (view)
344 SetViewportMetricsOnDecendants(view, *old_metrics, *new_metrics);
345 }
346
347 void ViewManagerClientImpl::OnViewHierarchyChanged(
348 Id view_id,
349 Id new_parent_id,
350 Id old_parent_id,
351 mojo::Array<ViewDataPtr> views) {
352 View* initial_parent = views.size() ? GetViewById(views[0]->parent_id) : NULL;
353
354 BuildViewTree(this, views, initial_parent);
355
356 View* new_parent = GetViewById(new_parent_id);
357 View* old_parent = GetViewById(old_parent_id);
358 View* view = GetViewById(view_id);
359 if (new_parent)
360 ViewPrivate(new_parent).LocalAddChild(view);
361 else
362 ViewPrivate(old_parent).LocalRemoveChild(view);
363 }
364
365 void ViewManagerClientImpl::OnViewReordered(Id view_id,
366 Id relative_view_id,
367 OrderDirection direction) {
368 View* view = GetViewById(view_id);
369 View* relative_view = GetViewById(relative_view_id);
370 if (view && relative_view)
371 ViewPrivate(view).LocalReorder(relative_view, direction);
372 }
373
374 void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
375 View* view = GetViewById(view_id);
376 if (view)
377 ViewPrivate(view).LocalDestroy();
378 }
379
380 void ViewManagerClientImpl::OnViewVisibilityChanged(Id view_id, bool visible) {
381 // TODO(sky): there is a race condition here. If this client and another
382 // client change the visibility at the same time the wrong value may be set.
383 // Deal with this some how.
384 View* view = GetViewById(view_id);
385 if (view)
386 ViewPrivate(view).LocalSetVisible(visible);
387 }
388
389 void ViewManagerClientImpl::OnViewDrawnStateChanged(Id view_id, bool drawn) {
390 View* view = GetViewById(view_id);
391 if (view)
392 ViewPrivate(view).LocalSetDrawn(drawn);
393 }
394
395 void ViewManagerClientImpl::OnViewSharedPropertyChanged(
396 Id view_id,
397 const String& name,
398 Array<uint8_t> new_data) {
399 View* view = GetViewById(view_id);
400 if (view) {
401 std::vector<uint8_t> data;
402 std::vector<uint8_t>* data_ptr = NULL;
403 if (!new_data.is_null()) {
404 data = new_data.To<std::vector<uint8_t>>();
405 data_ptr = &data;
406 }
407
408 view->SetSharedProperty(name, data_ptr);
409 }
410 }
411
412 void ViewManagerClientImpl::OnViewInputEvent(
413 Id view_id,
414 EventPtr event,
415 const Callback<void()>& ack_callback) {
416 View* view = GetViewById(view_id);
417 if (view) {
418 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(),
419 OnViewInputEvent(view, event));
420 }
421 ack_callback.Run();
422 }
423
424 void ViewManagerClientImpl::OnPerformAction(
425 Id view_id,
426 const String& name,
427 const Callback<void(bool)>& callback) {
428 View* view = GetViewById(view_id);
429 callback.Run(delegate_->OnPerformAction(view, name));
430 }
431
432 ////////////////////////////////////////////////////////////////////////////////
433 // ViewManagerClientImpl, WindowManagerObserver implementation:
434
435 void ViewManagerClientImpl::OnCaptureChanged(Id capture_view_id) {
436 View* gained_capture = GetViewById(capture_view_id);
437 View* lost_capture = capture_view_;
438 if (lost_capture) {
439 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(lost_capture).observers(),
440 OnViewFocusChanged(gained_capture, lost_capture));
441 }
442 capture_view_ = gained_capture;
443 if (gained_capture) {
444 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(gained_capture).observers(),
445 OnViewFocusChanged(gained_capture, lost_capture));
446 }
447 }
448
449 void ViewManagerClientImpl::OnFocusChanged(Id focused_view_id) {
450 View* focused = GetViewById(focused_view_id);
451 View* blurred = focused_view_;
452 if (blurred) {
453 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(blurred).observers(),
454 OnViewFocusChanged(focused, blurred));
455 }
456 focused_view_ = focused;
457 if (focused) {
458 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(focused).observers(),
459 OnViewFocusChanged(focused, blurred));
460 }
461 }
462
463 void ViewManagerClientImpl::OnActiveWindowChanged(Id active_view_id) {
464 View* activated = GetViewById(active_view_id);
465 View* deactivated = activated_view_;
466 if (deactivated) {
467 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(deactivated).observers(),
468 OnViewActivationChanged(activated, deactivated));
469 }
470 activated_view_ = activated;
471 if (activated) {
472 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(activated).observers(),
473 OnViewActivationChanged(activated, deactivated));
474 }
475 }
476
477 ////////////////////////////////////////////////////////////////////////////////
478 // ViewManagerClientImpl, private:
479
480 void ViewManagerClientImpl::RootDestroyed(View* root) {
481 DCHECK_EQ(root, root_);
482 root_ = nullptr;
483 }
484
485 void ViewManagerClientImpl::OnActionCompleted(bool success) {
486 if (!change_acked_callback_.is_null())
487 change_acked_callback_.Run();
488 }
489
490 Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() {
491 return [this](bool success) { OnActionCompleted(success); };
492 }
493
494 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698