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

Unified Diff: mojo/services/window_manager/window_manager_app.cc

Issue 1049993002: Get mojo_shell building inside chromium checkout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix presubmit Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: mojo/services/window_manager/window_manager_app.cc
diff --git a/mojo/services/window_manager/window_manager_app.cc b/mojo/services/window_manager/window_manager_app.cc
new file mode 100644
index 0000000000000000000000000000000000000000..99d2b356ee1b2c6063b953ec03fe5cbd6fc76cbb
--- /dev/null
+++ b/mojo/services/window_manager/window_manager_app.cc
@@ -0,0 +1,417 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/services/window_manager/window_manager_app.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/stl_util.h"
+#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "mojo/converters/input_events/input_events_type_converters.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_impl.h"
+#include "mojo/public/interfaces/application/shell.mojom.h"
+#include "mojo/services/window_manager/capture_controller.h"
+#include "mojo/services/window_manager/focus_controller.h"
+#include "mojo/services/window_manager/focus_rules.h"
+#include "mojo/services/window_manager/hit_test.h"
+#include "mojo/services/window_manager/view_event_dispatcher.h"
+#include "mojo/services/window_manager/view_target.h"
+#include "mojo/services/window_manager/view_targeter.h"
+#include "mojo/services/window_manager/window_manager_delegate.h"
+#include "third_party/mojo_services/src/view_manager/public/cpp/view.h"
+#include "third_party/mojo_services/src/view_manager/public/cpp/view_manager.h"
+
+using mojo::ApplicationConnection;
+using mojo::Id;
+using mojo::ServiceProvider;
+using mojo::View;
+using mojo::WindowManager;
+
+namespace window_manager {
+
+namespace {
+
+Id GetIdForView(View* view) {
+ return view ? view->id() : 0;
+}
+
+} // namespace
+
+// Used for calls to Embed() that occur before we've connected to the
+// ViewManager.
+struct WindowManagerApp::PendingEmbed {
+ mojo::String url;
+ mojo::InterfaceRequest<ServiceProvider> services;
+ mojo::ServiceProviderPtr exposed_services;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, public:
+
+WindowManagerApp::WindowManagerApp(
+ ViewManagerDelegate* view_manager_delegate,
+ WindowManagerDelegate* window_manager_delegate)
+ : shell_(nullptr),
+ wrapped_view_manager_delegate_(view_manager_delegate),
+ window_manager_delegate_(window_manager_delegate),
+ root_(nullptr) {
+}
+
+WindowManagerApp::~WindowManagerApp() {
+ // TODO(msw|sky): Should this destructor explicitly delete the ViewManager?
+ mojo::ViewManager* cached_view_manager = view_manager();
+ for (RegisteredViewIdSet::const_iterator it = registered_view_id_set_.begin();
+ cached_view_manager && it != registered_view_id_set_.end(); ++it) {
+ View* view = cached_view_manager->GetViewById(*it);
+ if (view && view == root_)
+ root_ = nullptr;
+ if (view)
+ view->RemoveObserver(this);
+ }
+ registered_view_id_set_.clear();
+ DCHECK(!root_);
+
+ STLDeleteElements(&connections_);
+}
+
+void WindowManagerApp::AddConnection(WindowManagerImpl* connection) {
+ DCHECK(connections_.find(connection) == connections_.end());
+ connections_.insert(connection);
+}
+
+void WindowManagerApp::RemoveConnection(WindowManagerImpl* connection) {
+ DCHECK(connections_.find(connection) != connections_.end());
+ connections_.erase(connection);
+}
+
+bool WindowManagerApp::SetCapture(Id view_id) {
+ View* view = view_manager()->GetViewById(view_id);
+ return view && SetCaptureImpl(view);
+}
+
+bool WindowManagerApp::FocusWindow(Id view_id) {
+ View* view = view_manager()->GetViewById(view_id);
+ return view && FocusWindowImpl(view);
+}
+
+bool WindowManagerApp::ActivateWindow(Id view_id) {
+ View* view = view_manager()->GetViewById(view_id);
+ return view && ActivateWindowImpl(view);
+}
+
+bool WindowManagerApp::IsReady() const {
+ return !!root_;
+}
+
+void WindowManagerApp::InitFocus(scoped_ptr<FocusRules> rules) {
+ DCHECK(root_);
+
+ focus_controller_.reset(new FocusController(rules.Pass()));
+ focus_controller_->AddObserver(this);
+ SetFocusController(root_, focus_controller_.get());
+
+ capture_controller_.reset(new CaptureController);
+ capture_controller_->AddObserver(this);
+ SetCaptureController(root_, capture_controller_.get());
+}
+
+void WindowManagerApp::Embed(
+ const mojo::String& url,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
+ if (view_manager()) {
+ window_manager_delegate_->Embed(url, services.Pass(),
+ exposed_services.Pass());
+ return;
+ }
+ scoped_ptr<PendingEmbed> pending_embed(new PendingEmbed);
+ pending_embed->url = url;
+ pending_embed->services = services.Pass();
+ pending_embed->exposed_services = exposed_services.Pass();
+ pending_embeds_.push_back(pending_embed.release());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, ApplicationDelegate implementation:
+
+void WindowManagerApp::Initialize(mojo::ApplicationImpl* impl) {
+ shell_ = impl->shell();
+ LaunchViewManager(impl);
+}
+
+bool WindowManagerApp::ConfigureIncomingConnection(
+ ApplicationConnection* connection) {
+ connection->AddService<WindowManager>(this);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, ViewManagerDelegate implementation:
+
+void WindowManagerApp::OnEmbed(
+ View* root,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
+ DCHECK(!root_);
+ root_ = root;
+
+ view_event_dispatcher_.reset(new ViewEventDispatcher);
+
+ RegisterSubtree(root_);
+
+ if (wrapped_view_manager_delegate_) {
+ wrapped_view_manager_delegate_->OnEmbed(root, services.Pass(),
+ exposed_services.Pass());
+ }
+
+ for (PendingEmbed* pending_embed : pending_embeds_) {
+ Embed(pending_embed->url, pending_embed->services.Pass(),
+ pending_embed->exposed_services.Pass());
+ }
+ pending_embeds_.clear();
+}
+
+void WindowManagerApp::OnViewManagerDisconnected(
+ mojo::ViewManager* view_manager) {
+ if (wrapped_view_manager_delegate_)
+ wrapped_view_manager_delegate_->OnViewManagerDisconnected(view_manager);
+
+ base::MessageLoop* message_loop = base::MessageLoop::current();
+ if (message_loop && message_loop->is_running())
+ message_loop->Quit();
+}
+
+bool WindowManagerApp::OnPerformAction(mojo::View* view,
+ const std::string& action) {
+ if (!view)
+ return false;
+ if (action == "capture")
+ return SetCaptureImpl(view);
+ if (action == "focus")
+ return FocusWindowImpl(view);
+ else if (action == "activate")
+ return ActivateWindowImpl(view);
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, ViewObserver implementation:
+
+void WindowManagerApp::OnTreeChanged(
+ const ViewObserver::TreeChangeParams& params) {
+ if (params.receiver != root_)
+ return;
+ DCHECK(params.old_parent || params.new_parent);
+ if (!params.target)
+ return;
+
+ if (params.new_parent) {
+ if (registered_view_id_set_.find(params.target->id()) ==
+ registered_view_id_set_.end()) {
+ RegisteredViewIdSet::const_iterator it =
+ registered_view_id_set_.find(params.new_parent->id());
+ DCHECK(it != registered_view_id_set_.end());
+ RegisterSubtree(params.target);
+ }
+ } else if (params.old_parent) {
+ UnregisterSubtree(params.target);
+ }
+}
+
+void WindowManagerApp::OnViewDestroying(View* view) {
+ Unregister(view);
+ if (view == root_) {
+ root_ = nullptr;
+ if (focus_controller_)
+ focus_controller_->RemoveObserver(this);
+ if (capture_controller_)
+ capture_controller_->RemoveObserver(this);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, ui::EventHandler implementation:
+
+void WindowManagerApp::OnEvent(ui::Event* event) {
+ if (!window_manager_client_)
+ return;
+
+ View* view = static_cast<ViewTarget*>(event->target())->view();
+ if (!view)
+ return;
+
+ if (event->IsKeyEvent()) {
+ const ui::KeyEvent* key_event = static_cast<const ui::KeyEvent*>(event);
+ if (key_event->type() == ui::ET_KEY_PRESSED) {
+ ui::Accelerator accelerator = ConvertEventToAccelerator(key_event);
+ if (accelerator_manager_.Process(accelerator))
+ return;
+ }
+ }
+
+ if (focus_controller_)
+ focus_controller_->OnEvent(event);
+
+ window_manager_client_->DispatchInputEventToView(view->id(),
+ mojo::Event::From(*event));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, mojo::FocusControllerObserver implementation:
+
+void WindowManagerApp::OnFocused(View* gained_focus) {
+ for (Connections::const_iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ (*it)->NotifyViewFocused(GetIdForView(gained_focus));
+ }
+}
+
+void WindowManagerApp::OnActivated(View* gained_active) {
+ for (Connections::const_iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ (*it)->NotifyWindowActivated(GetIdForView(gained_active));
+ }
+ if (gained_active)
+ gained_active->MoveToFront();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, mojo::CaptureControllerObserver implementation:
+
+void WindowManagerApp::OnCaptureChanged(View* gained_capture) {
+ for (Connections::const_iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ (*it)->NotifyCaptureChanged(GetIdForView(gained_capture));
+ }
+ if (gained_capture)
+ gained_capture->MoveToFront();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, private:
+
+bool WindowManagerApp::SetCaptureImpl(View* view) {
+ CHECK(view);
+ capture_controller_->SetCapture(view);
+ return capture_controller_->GetCapture() == view;
+}
+
+bool WindowManagerApp::FocusWindowImpl(View* view) {
+ CHECK(view);
+ focus_controller_->FocusView(view);
+ return focus_controller_->GetFocusedView() == view;
+}
+
+bool WindowManagerApp::ActivateWindowImpl(View* view) {
+ CHECK(view);
+ focus_controller_->ActivateView(view);
+ return focus_controller_->GetActiveView() == view;
+}
+
+void WindowManagerApp::RegisterSubtree(View* view) {
+ view->AddObserver(this);
+ DCHECK(registered_view_id_set_.find(view->id()) ==
+ registered_view_id_set_.end());
+ // All events pass through the root during dispatch, so we only need a handler
+ // installed there.
+ if (view == root_) {
+ ViewTarget* target = ViewTarget::TargetFromView(view);
+ target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter()));
+ target->AddPreTargetHandler(this);
+ view_event_dispatcher_->SetRootViewTarget(target);
+ }
+ registered_view_id_set_.insert(view->id());
+ View::Children::const_iterator it = view->children().begin();
+ for (; it != view->children().end(); ++it)
+ RegisterSubtree(*it);
+}
+
+void WindowManagerApp::UnregisterSubtree(View* view) {
+ for (View* child : view->children())
+ UnregisterSubtree(child);
+ Unregister(view);
+}
+
+void WindowManagerApp::Unregister(View* view) {
+ RegisteredViewIdSet::iterator it = registered_view_id_set_.find(view->id());
+ if (it == registered_view_id_set_.end()) {
+ // Because we unregister in OnViewDestroying() we can still get a subsequent
+ // OnTreeChanged for the same view. Ignore this one.
+ return;
+ }
+ view->RemoveObserver(this);
+ DCHECK(it != registered_view_id_set_.end());
+ registered_view_id_set_.erase(it);
+}
+
+void WindowManagerApp::DispatchInputEventToView(View* view,
+ mojo::EventPtr event) {
+ window_manager_client_->DispatchInputEventToView(view->id(), event.Pass());
+}
+
+void WindowManagerApp::SetViewportSize(const gfx::Size& size) {
+ window_manager_client_->SetViewportSize(mojo::Size::From(size));
+}
+
+void WindowManagerApp::LaunchViewManager(mojo::ApplicationImpl* app) {
+ // TODO(sky): figure out logic if this connection goes away.
+ view_manager_client_factory_.reset(
+ new mojo::ViewManagerClientFactory(shell_, this));
+
+ ApplicationConnection* view_manager_app =
+ app->ConnectToApplication("mojo:view_manager");
+ view_manager_app->ConnectToService(&view_manager_service_);
+
+ view_manager_app->AddService<WindowManagerInternal>(this);
+ view_manager_app->AddService<mojo::NativeViewportEventDispatcher>(this);
+
+ view_manager_app->ConnectToService(&window_manager_client_);
+}
+
+void WindowManagerApp::Create(
+ ApplicationConnection* connection,
+ mojo::InterfaceRequest<WindowManagerInternal> request) {
+ if (wm_internal_binding_.get()) {
+ VLOG(1) <<
+ "WindowManager allows only one WindowManagerInternal connection.";
+ return;
+ }
+ wm_internal_binding_.reset(
+ new mojo::Binding<WindowManagerInternal>(this, request.Pass()));
+}
+
+void WindowManagerApp::Create(ApplicationConnection* connection,
+ mojo::InterfaceRequest<WindowManager> request) {
+ WindowManagerImpl* wm = new WindowManagerImpl(this, false);
+ wm->Bind(request.PassMessagePipe());
+ // WindowManagerImpl is deleted when the connection has an error, or from our
+ // destructor.
+}
+
+void WindowManagerApp::Create(
+ mojo::ApplicationConnection* connection,
+ mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> request) {
+ new NativeViewportEventDispatcherImpl(this, request.Pass());
+}
+
+void WindowManagerApp::CreateWindowManagerForViewManagerClient(
+ uint16_t connection_id,
+ mojo::ScopedMessagePipeHandle window_manager_pipe) {
+ // TODO(sky): pass in |connection_id| for validation.
+ WindowManagerImpl* wm = new WindowManagerImpl(this, true);
+ wm->Bind(window_manager_pipe.Pass());
+ // WindowManagerImpl is deleted when the connection has an error, or from our
+ // destructor.
+}
+
+void WindowManagerApp::SetViewManagerClient(
+ mojo::ScopedMessagePipeHandle view_manager_client_request) {
+ view_manager_client_.reset(
+ mojo::ViewManagerClientFactory::WeakBindViewManagerToPipe(
+ mojo::MakeRequest<mojo::ViewManagerClient>(
+ view_manager_client_request.Pass()),
+ view_manager_service_.Pass(), shell_, this));
+}
+
+} // namespace window_manager
« no previous file with comments | « mojo/services/window_manager/window_manager_app.h ('k') | mojo/services/window_manager/window_manager_app_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698