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

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

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

Powered by Google App Engine
This is Rietveld 408576698