Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / mojo / services / public / cpp / view_manager / lib / view_manager_client_impl.cc
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/public/cpp/view_manager/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 "mojo/services/public/cpp/view_manager/lib/view_private.h"
16 #include "mojo/services/public/cpp/view_manager/util.h"
17 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
18 #include "mojo/services/public/cpp/view_manager/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.set_properties(
40       view_data->properties.To<std::map<std::string, std::vector<uint8_t>>>());
41   client->AddView(view);
42   private_view.LocalSetBounds(Rect(), *view_data->bounds);
43   if (parent)
44     ViewPrivate(parent).LocalAddChild(view);
45   return view;
46 }
47
48 View* BuildViewTree(ViewManagerClientImpl* client,
49                     const Array<ViewDataPtr>& views,
50                     View* initial_parent) {
51   std::vector<View*> parents;
52   View* root = NULL;
53   View* last_view = NULL;
54   if (initial_parent)
55     parents.push_back(initial_parent);
56   for (size_t i = 0; i < views.size(); ++i) {
57     if (last_view && views[i]->parent_id == last_view->id()) {
58       parents.push_back(last_view);
59     } else if (!parents.empty()) {
60       while (parents.back()->id() != views[i]->parent_id)
61         parents.pop_back();
62     }
63     View* view = AddViewToViewManager(
64         client, !parents.empty() ? parents.back() : NULL, views[i]);
65     if (!last_view)
66       root = view;
67     last_view = view;
68   }
69   return root;
70 }
71
72 // Responsible for removing a root from the ViewManager when that view is
73 // destroyed.
74 class RootObserver : public ViewObserver {
75  public:
76   explicit RootObserver(View* root) : root_(root) {}
77   ~RootObserver() override {}
78
79  private:
80   // Overridden from ViewObserver:
81   void OnViewDestroyed(View* view) override {
82     DCHECK_EQ(view, root_);
83     static_cast<ViewManagerClientImpl*>(
84         ViewPrivate(root_).view_manager())->RemoveRoot(root_);
85     view->RemoveObserver(this);
86     delete this;
87   }
88
89   View* root_;
90
91   DISALLOW_COPY_AND_ASSIGN(RootObserver);
92 };
93
94 ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate,
95                                              Shell* shell)
96     : connected_(false), connection_id_(0), next_id_(1), delegate_(delegate) {
97 }
98
99 ViewManagerClientImpl::~ViewManagerClientImpl() {
100   std::vector<View*> non_owned;
101   while (!views_.empty()) {
102     IdToViewMap::iterator it = views_.begin();
103     if (OwnsView(it->second->id())) {
104       it->second->Destroy();
105     } else {
106       non_owned.push_back(it->second);
107       views_.erase(it);
108     }
109   }
110   // Delete the non-owned views last. In the typical case these are roots. The
111   // exception is the window manager, which may know aboutother random views
112   // that it doesn't own.
113   // NOTE: we manually delete as we're a friend.
114   for (size_t i = 0; i < non_owned.size(); ++i)
115     delete non_owned[i];
116
117   delegate_->OnViewManagerDisconnected(this);
118 }
119
120 Id ViewManagerClientImpl::CreateView() {
121   DCHECK(connected_);
122   const Id view_id = MakeTransportId(connection_id_, ++next_id_);
123   service_->CreateView(view_id, ActionCompletedCallbackWithErrorCode());
124   return view_id;
125 }
126
127 void ViewManagerClientImpl::DestroyView(Id view_id) {
128   DCHECK(connected_);
129   service_->DeleteView(view_id, ActionCompletedCallback());
130 }
131
132 void ViewManagerClientImpl::AddChild(Id child_id, Id parent_id) {
133   DCHECK(connected_);
134   service_->AddView(parent_id, child_id, ActionCompletedCallback());
135 }
136
137 void ViewManagerClientImpl::RemoveChild(Id child_id, Id parent_id) {
138   DCHECK(connected_);
139   service_->RemoveViewFromParent(child_id, ActionCompletedCallback());
140 }
141
142 void ViewManagerClientImpl::Reorder(
143     Id view_id,
144     Id relative_view_id,
145     OrderDirection direction) {
146   DCHECK(connected_);
147   service_->ReorderView(view_id, relative_view_id, direction,
148                         ActionCompletedCallback());
149 }
150
151 bool ViewManagerClientImpl::OwnsView(Id id) const {
152   return HiWord(id) == connection_id_;
153 }
154
155 void ViewManagerClientImpl::SetBounds(Id view_id, const Rect& bounds) {
156   DCHECK(connected_);
157   service_->SetViewBounds(view_id, bounds.Clone(), ActionCompletedCallback());
158 }
159
160 void ViewManagerClientImpl::SetSurfaceId(Id view_id, SurfaceIdPtr surface_id) {
161   DCHECK(connected_);
162   if (surface_id.is_null())
163     return;
164   service_->SetViewSurfaceId(
165       view_id, surface_id.Pass(), ActionCompletedCallback());
166 }
167
168 void ViewManagerClientImpl::SetFocus(Id view_id) {
169   // In order for us to get here we had to have exposed a view, which implies we
170   // got a connection.
171   DCHECK(window_manager_.get());
172   window_manager_->FocusWindow(view_id, ActionCompletedCallback());
173 }
174
175 void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) {
176   DCHECK(connected_);
177   service_->SetViewVisibility(view_id, visible, ActionCompletedCallback());
178 }
179
180 void ViewManagerClientImpl::SetProperty(
181     Id view_id,
182     const std::string& name,
183     const std::vector<uint8_t>& data) {
184   DCHECK(connected_);
185   service_->SetViewProperty(view_id,
186                             String(name),
187                             Array<uint8_t>::From(data),
188                             ActionCompletedCallback());
189 }
190
191 void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
192   ServiceProviderPtr sp;
193   BindToProxy(new ServiceProviderImpl, &sp);
194   Embed(url, view_id, sp.Pass());
195 }
196
197 void ViewManagerClientImpl::Embed(
198     const String& url,
199     Id view_id,
200     ServiceProviderPtr service_provider) {
201   DCHECK(connected_);
202   service_->Embed(url, view_id, service_provider.Pass(),
203                   ActionCompletedCallback());
204 }
205
206 void ViewManagerClientImpl::AddView(View* view) {
207   DCHECK(views_.find(view->id()) == views_.end());
208   views_[view->id()] = view;
209 }
210
211 void ViewManagerClientImpl::RemoveView(Id view_id) {
212   IdToViewMap::iterator it = views_.find(view_id);
213   if (it != views_.end())
214     views_.erase(it);
215 }
216
217 ////////////////////////////////////////////////////////////////////////////////
218 // ViewManagerClientImpl, ViewManager implementation:
219
220 const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
221   return creator_url_;
222 }
223
224 const std::vector<View*>& ViewManagerClientImpl::GetRoots() const {
225   return roots_;
226 }
227
228 View* ViewManagerClientImpl::GetViewById(Id id) {
229   IdToViewMap::const_iterator it = views_.find(id);
230   return it != views_.end() ? it->second : NULL;
231 }
232
233 ////////////////////////////////////////////////////////////////////////////////
234 // ViewManagerClientImpl, InterfaceImpl overrides:
235
236 void ViewManagerClientImpl::OnConnectionEstablished() {
237   service_ = client();
238 }
239
240 ////////////////////////////////////////////////////////////////////////////////
241 // ViewManagerClientImpl, ViewManagerClient implementation:
242
243 void ViewManagerClientImpl::OnEmbed(
244     ConnectionSpecificId connection_id,
245     const String& creator_url,
246     ViewDataPtr root_data,
247     InterfaceRequest<ServiceProvider> parent_services,
248     ScopedMessagePipeHandle window_manager_pipe) {
249   if (!connected_) {
250     connected_ = true;
251     connection_id_ = connection_id;
252     creator_url_ = String::From(creator_url);
253   } else {
254     DCHECK_EQ(connection_id_, connection_id);
255     DCHECK_EQ(creator_url_, creator_url);
256   }
257
258   // A new root must not already exist as a root or be contained by an existing
259   // hierarchy visible to this view manager.
260   View* root = AddViewToViewManager(this, NULL, root_data);
261   roots_.push_back(root);
262   root->AddObserver(new RootObserver(root));
263
264   ServiceProviderImpl* exported_services = nullptr;
265   scoped_ptr<ServiceProvider> remote;
266
267   if (parent_services.is_pending()) {
268     // BindToRequest() binds the lifetime of |exported_services| to the pipe.
269     exported_services = new ServiceProviderImpl;
270     BindToRequest(exported_services, &parent_services);
271     remote.reset(exported_services->CreateRemoteServiceProvider());
272   }
273   window_manager_.Bind(window_manager_pipe.Pass());
274   window_manager_.set_client(this);
275   delegate_->OnEmbed(this, root, exported_services, remote.Pass());
276 }
277
278 void ViewManagerClientImpl::OnEmbeddedAppDisconnected(Id view_id) {
279   View* view = GetViewById(view_id);
280   if (view) {
281     FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(),
282                       OnViewEmbeddedAppDisconnected(view));
283   }
284 }
285
286 void ViewManagerClientImpl::OnViewBoundsChanged(Id view_id,
287                                                 RectPtr old_bounds,
288                                                 RectPtr new_bounds) {
289   View* view = GetViewById(view_id);
290   ViewPrivate(view).LocalSetBounds(*old_bounds, *new_bounds);
291 }
292
293 void ViewManagerClientImpl::OnViewHierarchyChanged(
294     Id view_id,
295     Id new_parent_id,
296     Id old_parent_id,
297     mojo::Array<ViewDataPtr> views) {
298   View* initial_parent = views.size() ?
299       GetViewById(views[0]->parent_id) : NULL;
300
301   BuildViewTree(this, views, initial_parent);
302
303   View* new_parent = GetViewById(new_parent_id);
304   View* old_parent = GetViewById(old_parent_id);
305   View* view = GetViewById(view_id);
306   if (new_parent)
307     ViewPrivate(new_parent).LocalAddChild(view);
308   else
309     ViewPrivate(old_parent).LocalRemoveChild(view);
310 }
311
312 void ViewManagerClientImpl::OnViewReordered(Id view_id,
313                                             Id relative_view_id,
314                                             OrderDirection direction) {
315   View* view = GetViewById(view_id);
316   View* relative_view = GetViewById(relative_view_id);
317   if (view && relative_view)
318     ViewPrivate(view).LocalReorder(relative_view, direction);
319 }
320
321 void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
322   View* view = GetViewById(view_id);
323   if (view)
324     ViewPrivate(view).LocalDestroy();
325 }
326
327 void ViewManagerClientImpl::OnViewVisibilityChanged(Id view_id, bool visible) {
328   // TODO(sky): there is a race condition here. If this client and another
329   // client change the visibility at the same time the wrong value may be set.
330   // Deal with this some how.
331   View* view = GetViewById(view_id);
332   if (view)
333     view->SetVisible(visible);
334 }
335
336 void ViewManagerClientImpl::OnViewDrawnStateChanged(Id view_id, bool drawn) {
337   View* view = GetViewById(view_id);
338   if (view)
339     ViewPrivate(view).LocalSetDrawn(drawn);
340 }
341
342 void ViewManagerClientImpl::OnViewPropertyChanged(
343     Id view_id,
344     const String& name,
345     Array<uint8_t> new_data) {
346   View* view = GetViewById(view_id);
347   if (view) {
348     std::vector<uint8_t> data;
349     std::vector<uint8_t>* data_ptr = NULL;
350     if (!new_data.is_null()) {
351       data = new_data.To<std::vector<uint8_t>>();
352       data_ptr = &data;
353     }
354
355     view->SetProperty(name, data_ptr);
356   }
357 }
358
359 void ViewManagerClientImpl::OnViewInputEvent(
360     Id view_id,
361     EventPtr event,
362     const Callback<void()>& ack_callback) {
363   View* view = GetViewById(view_id);
364   if (view) {
365     FOR_EACH_OBSERVER(ViewObserver,
366                       *ViewPrivate(view).observers(),
367                       OnViewInputEvent(view, event));
368   }
369   ack_callback.Run();
370 }
371
372 ////////////////////////////////////////////////////////////////////////////////
373 // ViewManagerClientImpl, WindowManagerClient implementation:
374
375 void ViewManagerClientImpl::OnCaptureChanged(Id old_capture_view_id,
376                                              Id new_capture_view_id) {}
377
378 void ViewManagerClientImpl::OnFocusChanged(Id old_focused_view_id,
379                                            Id new_focused_view_id) {
380   View* focused = GetViewById(new_focused_view_id);
381   View* blurred = GetViewById(old_focused_view_id);
382   if (blurred) {
383     FOR_EACH_OBSERVER(ViewObserver,
384                       *ViewPrivate(blurred).observers(),
385                       OnViewFocusChanged(focused, blurred));
386   }
387   if (focused) {
388     FOR_EACH_OBSERVER(ViewObserver,
389                       *ViewPrivate(focused).observers(),
390                       OnViewFocusChanged(focused, blurred));
391   }
392 }
393
394 void ViewManagerClientImpl::OnActiveWindowChanged(Id old_focused_window,
395                                                   Id new_focused_window) {}
396
397 ////////////////////////////////////////////////////////////////////////////////
398 // ViewManagerClientImpl, private:
399
400 void ViewManagerClientImpl::RemoveRoot(View* root) {
401   std::vector<View*>::iterator it =
402       std::find(roots_.begin(), roots_.end(), root);
403   if (it != roots_.end())
404     roots_.erase(it);
405 }
406
407 void ViewManagerClientImpl::OnActionCompleted(bool success) {
408   if (!change_acked_callback_.is_null())
409     change_acked_callback_.Run();
410 }
411
412 void ViewManagerClientImpl::OnActionCompletedWithErrorCode(ErrorCode code) {
413   OnActionCompleted(code == ERROR_CODE_NONE);
414 }
415
416 base::Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() {
417   return base::Bind(&ViewManagerClientImpl::OnActionCompleted,
418                     base::Unretained(this));
419 }
420
421 base::Callback<void(ErrorCode)>
422     ViewManagerClientImpl::ActionCompletedCallbackWithErrorCode() {
423   return base::Bind(&ViewManagerClientImpl::OnActionCompletedWithErrorCode,
424                     base::Unretained(this));
425 }
426
427 }  // namespace mojo