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

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

Issue 1391243003: Move //mojo/services/X/public/... to //mojo/services/X/... (part 4). (Closed) Base URL: https://github.com/domokit/mojo.git@no_public_3-x-no_public_2-x-no_public_1
Patch Set: copyright header Created 5 years, 2 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/public/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/public/cpp/lib/view_private.h"
13 #include "view_manager/public/cpp/util.h"
14 #include "view_manager/public/cpp/view_manager_delegate.h"
15 #include "view_manager/public/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(
148 Id view_id,
149 Id relative_view_id,
150 OrderDirection direction) {
151 DCHECK(service_);
152 service_->ReorderView(view_id, relative_view_id, direction,
153 ActionCompletedCallback());
154 }
155
156 bool ViewManagerClientImpl::OwnsView(Id id) const {
157 return HiWord(id) == connection_id_;
158 }
159
160 void ViewManagerClientImpl::SetBounds(Id view_id, const Rect& bounds) {
161 DCHECK(service_);
162 service_->SetViewBounds(view_id, bounds.Clone(), ActionCompletedCallback());
163 }
164
165 void ViewManagerClientImpl::SetSurfaceId(Id view_id, SurfaceIdPtr surface_id) {
166 DCHECK(service_);
167 if (surface_id.is_null())
168 return;
169 service_->SetViewSurfaceId(
170 view_id, surface_id.Pass(), ActionCompletedCallback());
171 }
172
173 void ViewManagerClientImpl::SetFocus(Id view_id) {
174 // In order for us to get here we had to have exposed a view, which implies we
175 // got a connection.
176 DCHECK(service_);
177 service_->PerformAction(view_id, "focus", ActionCompletedCallback());
178 }
179
180 void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) {
181 DCHECK(service_);
182 service_->SetViewVisibility(view_id, visible, ActionCompletedCallback());
183 }
184
185 void ViewManagerClientImpl::SetProperty(
186 Id view_id,
187 const std::string& name,
188 const std::vector<uint8_t>& data) {
189 DCHECK(service_);
190 service_->SetViewProperty(view_id,
191 String(name),
192 Array<uint8_t>::From(data),
193 ActionCompletedCallback());
194 }
195
196 void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
197 Embed(url, view_id, nullptr, nullptr);
198 }
199
200 void ViewManagerClientImpl::Embed(const String& url,
201 Id view_id,
202 InterfaceRequest<ServiceProvider> services,
203 ServiceProviderPtr exposed_services) {
204 DCHECK(service_);
205 service_->EmbedUrl(url, view_id, services.Pass(), exposed_services.Pass(),
206 ActionCompletedCallback());
207 }
208
209 void ViewManagerClientImpl::Embed(Id view_id, ViewManagerClientPtr client) {
210 DCHECK(service_);
211 service_->Embed(view_id, client.Pass(), ActionCompletedCallback());
212 }
213
214 void ViewManagerClientImpl::AddView(View* view) {
215 DCHECK(views_.find(view->id()) == views_.end());
216 views_[view->id()] = view;
217 }
218
219 void ViewManagerClientImpl::RemoveView(Id view_id) {
220 if (focused_view_ && focused_view_->id() == view_id)
221 OnFocusChanged(0);
222 if (capture_view_ && capture_view_->id() == view_id)
223 OnCaptureChanged(0);
224 if (activated_view_ && activated_view_->id() == view_id)
225 OnActiveWindowChanged(0);
226
227 IdToViewMap::iterator it = views_.find(view_id);
228 if (it != views_.end())
229 views_.erase(it);
230 }
231
232 void ViewManagerClientImpl::SetViewManagerService(
233 ViewManagerServicePtr service) {
234 DCHECK(!service_);
235 DCHECK(service);
236 service_ = service.Pass();
237 }
238 ////////////////////////////////////////////////////////////////////////////////
239 // ViewManagerClientImpl, ViewManager implementation:
240
241 Id ViewManagerClientImpl::CreateViewOnServer() {
242 DCHECK(service_);
243 const Id view_id = MakeTransportId(connection_id_, ++next_id_);
244 service_->CreateView(view_id, [this](ErrorCode code) {
245 OnActionCompleted(code == ErrorCode::NONE);
246 });
247 return view_id;
248 }
249
250 const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
251 return creator_url_;
252 }
253
254 View* ViewManagerClientImpl::GetRoot() {
255 return root_;
256 }
257
258 View* ViewManagerClientImpl::GetViewById(Id id) {
259 IdToViewMap::const_iterator it = views_.find(id);
260 return it != views_.end() ? it->second : NULL;
261 }
262
263 View* ViewManagerClientImpl::GetFocusedView() {
264 return focused_view_;
265 }
266
267 View* ViewManagerClientImpl::CreateView() {
268 View* view = new View(this, CreateViewOnServer());
269 AddView(view);
270 return view;
271 }
272
273 ////////////////////////////////////////////////////////////////////////////////
274 // ViewManagerClientImpl, ViewManagerClient implementation:
275
276 void ViewManagerClientImpl::OnEmbed(
277 ConnectionSpecificId connection_id,
278 const String& creator_url,
279 ViewDataPtr root_data,
280 ViewManagerServicePtr view_manager_service,
281 InterfaceRequest<ServiceProvider> services,
282 ServiceProviderPtr exposed_services,
283 ScopedMessagePipeHandle window_manager_pipe) {
284 if (view_manager_service) {
285 DCHECK(!service_);
286 service_ = view_manager_service.Pass();
287 }
288 connection_id_ = connection_id;
289 creator_url_ = String::From(creator_url);
290
291 DCHECK(!root_);
292 root_ = AddViewToViewManager(this, nullptr, root_data);
293 root_->AddObserver(new RootObserver(root_));
294
295 window_manager_.Bind(
296 InterfacePtrInfo<WindowManager>(window_manager_pipe.Pass(), 0u));
297 WindowManagerObserverPtr observer;
298 wm_observer_binding_.Bind(GetProxy(&observer));
299 // binding to |this| is safe here as |window_manager_| is bound to our
300 // lifetime.
301 window_manager_->GetFocusedAndActiveViews(
302 observer.Pass(),
303 [this](uint32_t capture_view_id, uint32_t focused_view_id,
304 uint32_t active_view_id) {
305 if (GetViewById(capture_view_id) != capture_view_)
306 OnCaptureChanged(capture_view_id);
307 if (GetViewById(focused_view_id) != focused_view_)
308 OnFocusChanged(focused_view_id);
309 if (GetViewById(active_view_id) != activated_view_)
310 OnActiveWindowChanged(active_view_id);
311 });
312
313 delegate_->OnEmbed(root_, services.Pass(), exposed_services.Pass());
314 }
315
316 void ViewManagerClientImpl::OnEmbeddedAppDisconnected(Id view_id) {
317 View* view = GetViewById(view_id);
318 if (view) {
319 FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(),
320 OnViewEmbeddedAppDisconnected(view));
321 }
322 }
323
324 void ViewManagerClientImpl::OnViewBoundsChanged(Id view_id,
325 RectPtr old_bounds,
326 RectPtr new_bounds) {
327 View* view = GetViewById(view_id);
328 ViewPrivate(view).LocalSetBounds(*old_bounds, *new_bounds);
329 }
330
331 namespace {
332
333 void SetViewportMetricsOnDecendants(View* root,
334 const ViewportMetrics& old_metrics,
335 const ViewportMetrics& new_metrics) {
336 ViewPrivate(root).LocalSetViewportMetrics(old_metrics, new_metrics);
337 const View::Children& children = root->children();
338 for (size_t i = 0; i < children.size(); ++i)
339 SetViewportMetricsOnDecendants(children[i], old_metrics, new_metrics);
340 }
341 }
342
343 void ViewManagerClientImpl::OnViewViewportMetricsChanged(
344 ViewportMetricsPtr old_metrics,
345 ViewportMetricsPtr new_metrics) {
346 View* view = GetRoot();
347 if (view)
348 SetViewportMetricsOnDecendants(view, *old_metrics, *new_metrics);
349 }
350
351 void ViewManagerClientImpl::OnViewHierarchyChanged(
352 Id view_id,
353 Id new_parent_id,
354 Id old_parent_id,
355 mojo::Array<ViewDataPtr> views) {
356 View* initial_parent = views.size() ?
357 GetViewById(views[0]->parent_id) : NULL;
358
359 BuildViewTree(this, views, initial_parent);
360
361 View* new_parent = GetViewById(new_parent_id);
362 View* old_parent = GetViewById(old_parent_id);
363 View* view = GetViewById(view_id);
364 if (new_parent)
365 ViewPrivate(new_parent).LocalAddChild(view);
366 else
367 ViewPrivate(old_parent).LocalRemoveChild(view);
368 }
369
370 void ViewManagerClientImpl::OnViewReordered(Id view_id,
371 Id relative_view_id,
372 OrderDirection direction) {
373 View* view = GetViewById(view_id);
374 View* relative_view = GetViewById(relative_view_id);
375 if (view && relative_view)
376 ViewPrivate(view).LocalReorder(relative_view, direction);
377 }
378
379 void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
380 View* view = GetViewById(view_id);
381 if (view)
382 ViewPrivate(view).LocalDestroy();
383 }
384
385 void ViewManagerClientImpl::OnViewVisibilityChanged(Id view_id, bool visible) {
386 // TODO(sky): there is a race condition here. If this client and another
387 // client change the visibility at the same time the wrong value may be set.
388 // Deal with this some how.
389 View* view = GetViewById(view_id);
390 if (view)
391 ViewPrivate(view).LocalSetVisible(visible);
392 }
393
394 void ViewManagerClientImpl::OnViewDrawnStateChanged(Id view_id, bool drawn) {
395 View* view = GetViewById(view_id);
396 if (view)
397 ViewPrivate(view).LocalSetDrawn(drawn);
398 }
399
400 void ViewManagerClientImpl::OnViewSharedPropertyChanged(
401 Id view_id,
402 const String& name,
403 Array<uint8_t> new_data) {
404 View* view = GetViewById(view_id);
405 if (view) {
406 std::vector<uint8_t> data;
407 std::vector<uint8_t>* data_ptr = NULL;
408 if (!new_data.is_null()) {
409 data = new_data.To<std::vector<uint8_t>>();
410 data_ptr = &data;
411 }
412
413 view->SetSharedProperty(name, data_ptr);
414 }
415 }
416
417 void ViewManagerClientImpl::OnViewInputEvent(
418 Id view_id,
419 EventPtr event,
420 const Callback<void()>& ack_callback) {
421 View* view = GetViewById(view_id);
422 if (view) {
423 FOR_EACH_OBSERVER(ViewObserver,
424 *ViewPrivate(view).observers(),
425 OnViewInputEvent(view, event));
426 }
427 ack_callback.Run();
428 }
429
430 void ViewManagerClientImpl::OnPerformAction(
431 Id view_id,
432 const String& name,
433 const Callback<void(bool)>& callback) {
434 View* view = GetViewById(view_id);
435 callback.Run(delegate_->OnPerformAction(view, name));
436 }
437
438 ////////////////////////////////////////////////////////////////////////////////
439 // ViewManagerClientImpl, WindowManagerObserver implementation:
440
441 void ViewManagerClientImpl::OnCaptureChanged(Id capture_view_id) {
442 View* gained_capture = GetViewById(capture_view_id);
443 View* lost_capture = capture_view_;
444 if (lost_capture) {
445 FOR_EACH_OBSERVER(ViewObserver,
446 *ViewPrivate(lost_capture).observers(),
447 OnViewFocusChanged(gained_capture, lost_capture));
448 }
449 capture_view_ = gained_capture;
450 if (gained_capture) {
451 FOR_EACH_OBSERVER(ViewObserver,
452 *ViewPrivate(gained_capture).observers(),
453 OnViewFocusChanged(gained_capture, lost_capture));
454 }
455 }
456
457 void ViewManagerClientImpl::OnFocusChanged(Id focused_view_id) {
458 View* focused = GetViewById(focused_view_id);
459 View* blurred = focused_view_;
460 if (blurred) {
461 FOR_EACH_OBSERVER(ViewObserver,
462 *ViewPrivate(blurred).observers(),
463 OnViewFocusChanged(focused, blurred));
464 }
465 focused_view_ = focused;
466 if (focused) {
467 FOR_EACH_OBSERVER(ViewObserver,
468 *ViewPrivate(focused).observers(),
469 OnViewFocusChanged(focused, blurred));
470 }
471 }
472
473 void ViewManagerClientImpl::OnActiveWindowChanged(Id active_view_id) {
474 View* activated = GetViewById(active_view_id);
475 View* deactivated = activated_view_;
476 if (deactivated) {
477 FOR_EACH_OBSERVER(ViewObserver,
478 *ViewPrivate(deactivated).observers(),
479 OnViewActivationChanged(activated, deactivated));
480 }
481 activated_view_ = activated;
482 if (activated) {
483 FOR_EACH_OBSERVER(ViewObserver,
484 *ViewPrivate(activated).observers(),
485 OnViewActivationChanged(activated, deactivated));
486 }
487 }
488
489 ////////////////////////////////////////////////////////////////////////////////
490 // ViewManagerClientImpl, private:
491
492 void ViewManagerClientImpl::RootDestroyed(View* root) {
493 DCHECK_EQ(root, root_);
494 root_ = nullptr;
495 }
496
497 void ViewManagerClientImpl::OnActionCompleted(bool success) {
498 if (!change_acked_callback_.is_null())
499 change_acked_callback_.Run();
500 }
501
502 Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() {
503 return [this](bool success) { OnActionCompleted(success); };
504 }
505
506 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698