| OLD | NEW | 
|---|
| (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 | 
| OLD | NEW | 
|---|