Commit 16199f15 authored by ben@chromium.org's avatar ben@chromium.org

Add the skeleton of a window manager service and a CreateWindow method.

R=sky@chromium.org
BUG=

Review URL: https://codereview.chromium.org/396563002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283786 0039d316-1c4b-4281-b951-d872f2087c98
parent 93675408
...@@ -110,6 +110,8 @@ ...@@ -110,6 +110,8 @@
'mojo_aura_demo', 'mojo_aura_demo',
'mojo_aura_demo_init', 'mojo_aura_demo_init',
'mojo_browser', 'mojo_browser',
'mojo_core_window_manager',
'mojo_core_window_manager_unittests',
'mojo_demo_launcher', 'mojo_demo_launcher',
'mojo_embedded_app', 'mojo_embedded_app',
'mojo_keyboard', 'mojo_keyboard',
......
...@@ -633,6 +633,20 @@ ...@@ -633,6 +633,20 @@
'services/test_service/test_request_tracker_impl.h', 'services/test_service/test_request_tracker_impl.h',
], ],
}, },
{
'target_name': 'mojo_core_window_manager_bindings',
'type': 'static_library',
'sources': [
'services/public/interfaces/window_manager/window_manager.mojom',
],
'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
'export_dependent_settings': [
'mojo_cpp_bindings',
],
'dependencies': [
'mojo_cpp_bindings',
],
},
], ],
'conditions': [ 'conditions': [
['use_aura==1', { ['use_aura==1', {
...@@ -761,6 +775,63 @@ ...@@ -761,6 +775,63 @@
}, },
'includes': [ 'build/package_app.gypi' ], 'includes': [ 'build/package_app.gypi' ],
}, },
{
'target_name': 'mojo_core_window_manager',
'type': 'loadable_module',
'dependencies': [
'../base/base.gyp:base',
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/wm/wm.gyp:wm',
'mojo_application',
'mojo_aura_support',
'mojo_common_lib',
'mojo_core_window_manager_bindings',
'mojo_environment_chromium',
'mojo_view_manager_lib',
'<(mojo_system_for_loadable_module)',
],
'sources': [
'public/cpp/application/lib/mojo_main_chromium.cc',
'services/window_manager/window_manager_app.cc',
'services/window_manager/window_manager_app.h',
'services/window_manager/window_manager_service_impl.cc',
'services/window_manager/window_manager_service_impl.h',
],
},
{
'target_name': 'mojo_core_window_manager_unittests',
'type': 'executable',
'dependencies': [
'../base/base.gyp:test_support_base',
'../testing/gtest.gyp:gtest',
'../ui/gl/gl.gyp:gl',
'mojo_core_window_manager_bindings',
'mojo_environment_chromium',
'mojo_service_manager',
'mojo_shell_test_support',
'mojo_system_impl',
'mojo_view_manager_bindings',
],
'sources': [
'services/window_manager/window_manager_api_unittest.cc',
'services/window_manager/window_manager_unittests.cc',
],
'conditions': [
['OS=="linux"', {
'dependencies': [
'../third_party/mesa/mesa.gyp:osmesa',
'mojo_native_viewport_service',
],
}],
['use_x11==1', {
'dependencies': [
'../ui/gfx/x/gfx_x11.gyp:gfx_x11',
],
}],
],
},
], ],
}], }],
['OS=="linux"', { ['OS=="linux"', {
......
// 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.
module mojo {
[Client=WindowManagerClient]
interface WindowManagerService {
OpenWindow() => (uint32 node_id);
SetCapture(uint32 node_id) => (bool success);
};
[Client=WindowManagerService]
interface WindowManagerClient {
// Called when the window manager is ready to use (in the event a client
// connects to it before it has been initialized).
OnWindowManagerReady();
// TODO(beng): how is the WM supposed to know if a node is known to a client
// or not?
OnCaptureChanged(uint32 old_capture_node_id, uint32 new_capture_node_id);
};
}
include_rules = [
"+mojo/aura",
"+mojo/service_manager",
"+mojo/services/native_viewport",
"+mojo/services/public",
"+ui/gfx",
"+ui/gl",
"+ui/wm",
]
// 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 "base/bind.h"
#include "mojo/service_manager/service_manager.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
#include "mojo/shell/shell_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace {
// Callback from EmbedRoot(). |result| is the result of the
// Embed() call and |run_loop| the nested RunLoop.
void ResultCallback(bool* result_cache, base::RunLoop* run_loop, bool result) {
*result_cache = result;
run_loop->Quit();
}
// Responsible for establishing the initial ViewManagerService connection.
// Blocks until result is determined.
bool EmbedRoot(view_manager::ViewManagerInitService* view_manager_init,
const std::string& url) {
bool result = false;
base::RunLoop run_loop;
view_manager_init->EmbedRoot(url,
base::Bind(&ResultCallback, &result, &run_loop));
run_loop.Run();
return result;
}
void OpenWindowCallback(view_manager::Id* id,
base::RunLoop* run_loop,
view_manager::Id window_id) {
*id = window_id;
run_loop->Quit();
}
view_manager::Id OpenWindow(WindowManagerService* window_manager) {
base::RunLoop run_loop;
view_manager::Id id;
window_manager->OpenWindow(
base::Bind(&OpenWindowCallback, &id, &run_loop));
run_loop.Run();
return id;
}
class TestWindowManagerClient : public WindowManagerClient {
public:
explicit TestWindowManagerClient(base::RunLoop* run_loop)
: run_loop_(run_loop) {}
virtual ~TestWindowManagerClient() {}
private:
// Overridden from WindowManagerClient:
virtual void OnWindowManagerReady() MOJO_OVERRIDE {
run_loop_->Quit();
}
virtual void OnCaptureChanged(
view_manager::Id old_capture_node_id,
view_manager::Id new_capture_node_id) MOJO_OVERRIDE {}
base::RunLoop* run_loop_;
DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient);
};
} // namespace
class WindowManagerApiTest : public testing::Test {
public:
WindowManagerApiTest() {}
virtual ~WindowManagerApiTest() {}
protected:
WindowManagerServicePtr window_manager_;
private:
// Overridden from testing::Test:
virtual void SetUp() MOJO_OVERRIDE {
test_helper_.Init();
test_helper_.service_manager()->ConnectToService(
GURL("mojo:mojo_view_manager"),
&view_manager_init_);
ASSERT_TRUE(EmbedRoot(view_manager_init_.get(),
"mojo:mojo_core_window_manager"));
ConnectToWindowManager();
}
virtual void TearDown() MOJO_OVERRIDE {}
void ConnectToWindowManager() {
test_helper_.service_manager()->ConnectToService(
GURL("mojo:mojo_core_window_manager"),
&window_manager_);
base::RunLoop connect_loop;
window_manager_client_ = new TestWindowManagerClient(&connect_loop);
window_manager_.set_client(window_manager_client_);
connect_loop.Run();
}
base::MessageLoop loop_;
shell::ShellTestHelper test_helper_;
view_manager::ViewManagerInitServicePtr view_manager_init_;
TestWindowManagerClient* window_manager_client_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest);
};
TEST_F(WindowManagerApiTest, OpenWindow) {
OpenWindow(window_manager_.get());
}
} // namespace mojo
// 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 "mojo/aura/aura_init.h"
#include "mojo/aura/window_tree_host_mojo.h"
#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/services/public/cpp/view_manager/node.h"
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/window_manager/window_manager_service_impl.h"
#include "ui/wm/core/capture_controller.h"
namespace mojo {
////////////////////////////////////////////////////////////////////////////////
// WindowManagerApp, public:
WindowManagerApp::WindowManagerApp() : view_manager_(NULL), root_(NULL) {}
WindowManagerApp::~WindowManagerApp() {}
void WindowManagerApp::AddConnection(WindowManagerServiceImpl* connection) {
DCHECK(connections_.find(connection) == connections_.end());
connections_.insert(connection);
}
void WindowManagerApp::RemoveConnection(WindowManagerServiceImpl* connection) {
DCHECK(connections_.find(connection) != connections_.end());
connections_.erase(connection);
}
view_manager::Id WindowManagerApp::OpenWindow() {
view_manager::Node* node = view_manager::Node::Create(view_manager_);
root_->AddChild(node);
return node->id();
}
void WindowManagerApp::SetCapture(view_manager::Id node) {
capture_client_->capture_client()->SetCapture(GetWindowForNodeId(node));
// TODO(beng): notify connected clients that capture has changed, probably
// by implementing some capture-client observer.
}
bool WindowManagerApp::IsReady() const {
return view_manager_ && root_;
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerApp, ApplicationDelegate implementation:
void WindowManagerApp::Initialize(ApplicationImpl* impl) {
aura_init_.reset(new AuraInit);
}
bool WindowManagerApp::ConfigureIncomingConnection(
ApplicationConnection* connection) {
connection->AddService<WindowManagerServiceImpl>(this);
view_manager::ViewManager::ConfigureIncomingConnection(connection, this);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerApp, view_manager::ViewManagerDelegate implementation:
void WindowManagerApp::OnRootAdded(view_manager::ViewManager* view_manager,
view_manager::Node* root) {
DCHECK(!view_manager_ && !root_);
view_manager_ = view_manager;
root_ = root;
window_tree_host_.reset(new WindowTreeHostMojo(root_, this));
capture_client_.reset(
new wm::ScopedCaptureClient(window_tree_host_->window()));
// TODO(beng): Create the universe.
for (Connections::const_iterator it = connections_.begin();
it != connections_.end(); ++it) {
(*it)->NotifyReady();
}
}
void WindowManagerApp::OnViewManagerDisconnected(
view_manager::ViewManager* view_manager) {
DCHECK_EQ(view_manager_, view_manager);
view_manager_ = NULL;
base::MessageLoop::current()->Quit();
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerApp, WindowTreeHostMojoDelegate implementation:
void WindowManagerApp::CompositorContentsChanged(const SkBitmap& bitmap) {
// We draw nothing.
NOTREACHED();
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerApp, private:
aura::Window* WindowManagerApp::GetWindowForNodeId(
view_manager::Id node) const {
NOTIMPLEMENTED();
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
// ApplicationDelegate, public:
// static
ApplicationDelegate* ApplicationDelegate::Create() {
return new WindowManagerApp;
}
} // namespace mojo
// 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.
#ifndef MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
#include <set>
#include "base/memory/scoped_ptr.h"
#include "mojo/aura/window_tree_host_mojo_delegate.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
namespace aura {
class Window;
}
namespace wm {
class ScopedCaptureClient;
}
namespace mojo {
class AuraInit;
class WindowManagerServiceImpl;
class WindowTreeHostMojo;
class WindowManagerApp : public ApplicationDelegate,
public view_manager::ViewManagerDelegate,
public WindowTreeHostMojoDelegate {
public:
WindowManagerApp();
virtual ~WindowManagerApp();
void AddConnection(WindowManagerServiceImpl* connection);
void RemoveConnection(WindowManagerServiceImpl* connection);
view_manager::Id OpenWindow();
void SetCapture(view_manager::Id node);
bool IsReady() const;
private:
typedef std::set<WindowManagerServiceImpl*> Connections;
// Overridden from ApplicationDelegate:
virtual void Initialize(ApplicationImpl* impl) MOJO_OVERRIDE;
virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
MOJO_OVERRIDE;
// Overridden from view_manager::ViewManagerDelegate:
virtual void OnRootAdded(view_manager::ViewManager* view_manager,
view_manager::Node* root) MOJO_OVERRIDE;
virtual void OnViewManagerDisconnected(
view_manager::ViewManager* view_manager) MOJO_OVERRIDE;
// Overridden from WindowTreeHostMojoDelegate:
virtual void CompositorContentsChanged(const SkBitmap& bitmap) MOJO_OVERRIDE;
aura::Window* GetWindowForNodeId(view_manager::Id node) const;
view_manager::ViewManager* view_manager_;
view_manager::Node* root_;
scoped_ptr<AuraInit> aura_init_;
scoped_ptr<WindowTreeHostMojo> window_tree_host_;
scoped_ptr<wm::ScopedCaptureClient> capture_client_;
Connections connections_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerApp);
};
} // namespace mojo
#endif // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
// 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_service_impl.h"
#include "mojo/services/window_manager/window_manager_app.h"
namespace mojo {
////////////////////////////////////////////////////////////////////////////////
// WindowManagerServiceImpl, public:
WindowManagerServiceImpl::WindowManagerServiceImpl(
ApplicationConnection* connection,
WindowManagerApp* window_manager)
: window_manager_(window_manager) {
window_manager_->AddConnection(this);
}
WindowManagerServiceImpl::~WindowManagerServiceImpl() {
window_manager_->RemoveConnection(this);
}
void WindowManagerServiceImpl::NotifyReady() {
client()->OnWindowManagerReady();
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerServiceImpl, WindowManager implementation:
void WindowManagerServiceImpl::OpenWindow(
const Callback<void(view_manager::Id)>& callback) {
view_manager::Id id = window_manager_->OpenWindow();
callback.Run(id);
}
void WindowManagerServiceImpl::SetCapture(
view_manager::Id node,
const Callback<void(bool)>& callback) {
window_manager_->SetCapture(node);
callback.Run(true);
}
////////////////////////////////////////////////////////////////////////////////
// WindowManagerServiceImpl, InterfaceImpl overrides:
void WindowManagerServiceImpl::OnConnectionEstablished() {
// If the connection was established prior to the window manager being
// embedded by the view manager, |window_manager_|'s ViewManagerDelegate
// impl will call NotifyReady() when it is.
if (window_manager_->IsReady())
NotifyReady();
}
} // namespace mojo
// 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.
#ifndef MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE_IMPL_H_
#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE_IMPL_H_
#include "base/basictypes.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
namespace mojo {
class ApplicationConnection;
class WindowManagerApp;
class WindowManagerServiceImpl : public InterfaceImpl<WindowManagerService> {
public:
WindowManagerServiceImpl(ApplicationConnection* connection,
WindowManagerApp* manager);
virtual ~WindowManagerServiceImpl();
void NotifyReady();
private:
// Overridden from WindowManagerService:
virtual void OpenWindow(
const Callback<void(view_manager::Id)>& callback) MOJO_OVERRIDE;
virtual void SetCapture(view_manager::Id node,
const Callback<void(bool)>& callback) MOJO_OVERRIDE;
// Overridden from InterfaceImpl:
virtual void OnConnectionEstablished() MOJO_OVERRIDE;
WindowManagerApp* window_manager_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerServiceImpl);
};
} // namespace mojo
#endif // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE_IMPL_H_
// 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 "base/bind.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/test_suite.h"
#include "ui/gl/gl_surface.h"
#if defined(USE_X11)
#include "ui/gfx/x/x11_connection.h"
#endif
namespace mojo {
class WindowManagerTestSuite : public base::TestSuite {
public:
WindowManagerTestSuite(int argc, char** argv) : TestSuite(argc, argv) {}
virtual ~WindowManagerTestSuite() {}
protected:
virtual void Initialize() OVERRIDE {
#if defined(USE_X11)
// Each test ends up creating a new thread for the native viewport service.
// In other words we'll use X on different threads, so tell it that.
gfx::InitializeThreadedX11();
#endif
base::TestSuite::Initialize();
gfx::GLSurface::InitializeOneOffForTests();
}
private:
DISALLOW_COPY_AND_ASSIGN(WindowManagerTestSuite);
};
} // namespace mojo
int main(int argc, char** argv) {
mojo::WindowManagerTestSuite test_suite(argc, argv);
return base::LaunchUnitTests(
argc, argv, base::Bind(&TestSuite::Run, base::Unretained(&test_suite)));
}
...@@ -5,8 +5,12 @@ ...@@ -5,8 +5,12 @@
#include "mojo/shell/shell_test_helper.h" #include "mojo/shell/shell_test_helper.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/path_service.h"
#include "mojo/shell/init.h" #include "mojo/shell/init.h"
#include "net/base/filename_util.h"
namespace mojo { namespace mojo {
namespace shell { namespace shell {
...@@ -22,6 +26,10 @@ ShellTestHelper::~ShellTestHelper() { ...@@ -22,6 +26,10 @@ ShellTestHelper::~ShellTestHelper() {
void ShellTestHelper::Init() { void ShellTestHelper::Init() {
context_.reset(new Context); context_.reset(new Context);
test_api_.reset(new ServiceManager::TestAPI(context_->service_manager())); test_api_.reset(new ServiceManager::TestAPI(context_->service_manager()));
base::FilePath service_dir;
CHECK(PathService::Get(base::DIR_MODULE, &service_dir));
context_->mojo_url_resolver()->set_origin(
net::FilePathToFileURL(service_dir).spec());
} }
void ShellTestHelper::SetLoaderForURL(scoped_ptr<ServiceLoader> loader, void ShellTestHelper::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment