diff options
author | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-18 16:31:01 +0000 |
---|---|---|
committer | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-18 16:31:01 +0000 |
commit | f7a0b4d2c8f13d1d25c79bd1bd63568adf057a20 (patch) | |
tree | 98f95d695fdd24dc7dc1e54168c901e82e7031dc /ui/viewer | |
parent | 68f5b577e717e0cccbd012b2c73fe5f71ea78317 (diff) | |
download | chromium_src-f7a0b4d2c8f13d1d25c79bd1bd63568adf057a20.zip chromium_src-f7a0b4d2c8f13d1d25c79bd1bd63568adf057a20.tar.gz chromium_src-f7a0b4d2c8f13d1d25c79bd1bd63568adf057a20.tar.bz2 |
Bunch of boilerplate to set up a process, ipc, etc.
Only hooked up in "aura_demo --viewer" right now, and doesn't actually accomplish anything other than opening a window yet.
Review URL: https://codereview.chromium.org/10872002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157367 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/viewer')
-rw-r--r-- | ui/viewer/viewer.gyp | 34 | ||||
-rw-r--r-- | ui/viewer/viewer_host_win.cc | 53 | ||||
-rw-r--r-- | ui/viewer/viewer_host_win.h | 36 | ||||
-rw-r--r-- | ui/viewer/viewer_ipc_server.cc | 98 | ||||
-rw-r--r-- | ui/viewer/viewer_ipc_server.h | 57 | ||||
-rw-r--r-- | ui/viewer/viewer_main.cc | 34 | ||||
-rw-r--r-- | ui/viewer/viewer_message_generator.cc | 33 | ||||
-rw-r--r-- | ui/viewer/viewer_message_generator.h | 7 | ||||
-rw-r--r-- | ui/viewer/viewer_messages.h | 26 | ||||
-rw-r--r-- | ui/viewer/viewer_process.cc | 67 | ||||
-rw-r--r-- | ui/viewer/viewer_process.h | 69 |
11 files changed, 514 insertions, 0 deletions
diff --git a/ui/viewer/viewer.gyp b/ui/viewer/viewer.gyp new file mode 100644 index 0000000..750b583 --- /dev/null +++ b/ui/viewer/viewer.gyp @@ -0,0 +1,34 @@ +# Copyright (c) 2012 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'viewer', + 'type': 'static_library', + 'dependencies': [ + '../../base/base.gyp:base', + '../../skia/skia.gyp:skia', + ], + 'sources': [ + 'viewer_host_win.cc', + 'viewer_host_win.h', + 'viewer_ipc_server.cc', + 'viewer_ipc_server.h', + 'viewer_main.cc', + 'viewer_message_generator.cc', + 'viewer_message_generator.h', + 'viewer_process.cc', + 'viewer_process.h', + ], + 'include_dirs': [ + '..', + ], + }, + ], +} + diff --git a/ui/viewer/viewer_host_win.cc b/ui/viewer/viewer_host_win.cc new file mode 100644 index 0000000..fe21c55 --- /dev/null +++ b/ui/viewer/viewer_host_win.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2012 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 "ui/viewer/viewer_host_win.h" + +#include "ui/aura/client/stacking_client.h" +#include "ui/aura/display_manager.h" +#include "ui/aura/env.h" +#include "ui/aura/focus_manager.h" +#include "ui/aura/root_window.h" +#include "ui/aura/shared/root_window_capture_client.h" +#include "ui/aura/single_display_manager.h" + +class ViewerStackingClient : public aura::client::StackingClient { + public: + explicit ViewerStackingClient(aura::RootWindow* root_window) + : root_window_(root_window) { + aura::client::SetStackingClient(this); + } + + virtual ~ViewerStackingClient() { + aura::client::SetStackingClient(NULL); + } + + // Overridden from aura::client::StackingClient: + virtual aura::Window* GetDefaultParent(aura::Window* window, + const gfx::Rect& bounds) OVERRIDE { + return root_window_; + } + + private: + aura::RootWindow* root_window_; + + scoped_ptr<aura::shared::RootWindowCaptureClient> capture_client_; + + DISALLOW_COPY_AND_ASSIGN(ViewerStackingClient); +}; + +ViewerHostWin::ViewerHostWin() { + aura::DisplayManager::set_use_fullscreen_host_window(true); + aura::Env::GetInstance()->SetDisplayManager(new aura::SingleDisplayManager); + root_window_.reset(aura::DisplayManager::CreateRootWindowForPrimaryDisplay()); + root_window_capture_client_.reset( + new aura::shared::RootWindowCaptureClient(root_window_.get())); + focus_manager_.reset(new aura::FocusManager); + root_window_->set_focus_manager(focus_manager_.get()); + stacking_client_.reset(new ViewerStackingClient(root_window_.get())); + root_window_->ShowRootWindow(); +} + +ViewerHostWin::~ViewerHostWin() { +} diff --git a/ui/viewer/viewer_host_win.h b/ui/viewer/viewer_host_win.h new file mode 100644 index 0000000..57da87e --- /dev/null +++ b/ui/viewer/viewer_host_win.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 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 UI_VIEWER_VIEWER_HOST_WIN_H_ +#define UI_VIEWER_VIEWER_HOST_WIN_H_ + +#include "base/memory/scoped_ptr.h" + +class ViewerStackingClient; + +namespace aura { +class FocusManager; +class RootWindow; + +namespace shared { +class RootWindowCaptureClient; +} + +} + +class ViewerHostWin { + public: + ViewerHostWin(); + virtual ~ViewerHostWin(); + + private: + scoped_ptr<aura::RootWindow> root_window_; + scoped_ptr<aura::shared::RootWindowCaptureClient> root_window_capture_client_; + scoped_ptr<ViewerStackingClient> stacking_client_; + scoped_ptr<aura::FocusManager> focus_manager_; + + DISALLOW_COPY_AND_ASSIGN(ViewerHostWin); +}; + +#endif // UI_VIEWER_VIEWER_HOST_WIN_H_ diff --git a/ui/viewer/viewer_ipc_server.cc b/ui/viewer/viewer_ipc_server.cc new file mode 100644 index 0000000..578d193 --- /dev/null +++ b/ui/viewer/viewer_ipc_server.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2012 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 "ui/viewer/viewer_ipc_server.h" + +#include "ui/viewer/viewer_messages.h" +#include "ui/viewer/viewer_process.h" +#include "ipc/ipc_logging.h" + +ViewerIPCServer::ViewerIPCServer(const IPC::ChannelHandle& channel_handle) + : client_connected_(false), channel_handle_(channel_handle) { +} + +ViewerIPCServer::~ViewerIPCServer() { +#ifdef IPC_MESSAGE_LOG_ENABLED + IPC::Logging::GetInstance()->SetIPCSender(NULL); +#endif + + channel_->RemoveFilter(sync_message_filter_.get()); +} + +bool ViewerIPCServer::Init() { +#ifdef IPC_MESSAGE_LOG_ENABLED + IPC::Logging::GetInstance()->SetIPCSender(this); +#endif + sync_message_filter_ = + new IPC::SyncMessageFilter(g_viewer_process->shutdown_event()); + CreateChannel(); + return true; +} + +bool ViewerIPCServer::Send(IPC::Message* msg) { + if (!channel_.get()) { + delete msg; + return false; + } + + return channel_->Send(msg); +} + +bool ViewerIPCServer::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + // When we get a message, always mark the client as connected. The + // ChannelProxy::Context is only letting OnChannelConnected get called once, + // so on the Mac and Linux, we never would set client_connected_ to true + // again on subsequent connections. + client_connected_ = true; + IPC_BEGIN_MESSAGE_MAP(ViewerIPCServer, msg) + IPC_MESSAGE_HANDLER(ViewerMsg_PbufferHandle, + OnPbufferHandle) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void ViewerIPCServer::OnChannelConnected(int32 peer_pid) { + DCHECK(!client_connected_); + client_connected_ = true; +} + +void ViewerIPCServer::OnChannelError() { + // When a client (typically a browser process) disconnects, the pipe is + // closed and we get an OnChannelError. Since we want to keep servicing + // client requests, we will recreate the channel. + bool client_was_connected = client_connected_; + client_connected_ = false; + if (client_was_connected) { + if (g_viewer_process->HandleClientDisconnect()) { +#if defined(OS_WIN) + // On Windows, once an error on a named pipe occurs, the named pipe is no + // longer valid and must be re-created. This is not the case on Mac or + // Linux. + CreateChannel(); +#endif + } + } else { + // If the client was never even connected we had an error connecting. + if (!client_connected_) { + LOG(ERROR) << "Unable to open viewer ipc channel " + << "named: " << channel_handle_.name; + } + } +} + +void ViewerIPCServer::OnPbufferHandle(const std::string& todo) { + NOTREACHED(); +} + +void ViewerIPCServer::CreateChannel() { + channel_.reset(NULL); // Tear down the existing channel, if any. + channel_.reset(new IPC::SyncChannel(channel_handle_, + IPC::Channel::MODE_NAMED_SERVER, this, + g_viewer_process->io_message_loop_proxy(), true, + g_viewer_process->shutdown_event())); + DCHECK(sync_message_filter_.get()); + channel_->AddFilter(sync_message_filter_.get()); +} diff --git a/ui/viewer/viewer_ipc_server.h b/ui/viewer/viewer_ipc_server.h new file mode 100644 index 0000000..8ab2bd0 --- /dev/null +++ b/ui/viewer/viewer_ipc_server.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012 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 UI_VIEWER_VIEWER_IPC_SERVER_H_ +#define UI_VIEWER_VIEWER_IPC_SERVER_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "ipc/ipc_channel_handle.h" +#include "ipc/ipc_listener.h" +#include "ipc/ipc_sync_channel.h" +#include "ipc/ipc_sync_message_filter.h" +#include "ipc/ipc_sender.h" + +// This class handles IPC commands for the Viewer process. +class ViewerIPCServer : public IPC::Listener, public IPC::Sender { + public: + explicit ViewerIPCServer(const IPC::ChannelHandle& handle); + virtual ~ViewerIPCServer(); + + bool Init(); + + // IPC::Sender implementation. + virtual bool Send(IPC::Message* msg) OVERRIDE; + + IPC::SyncChannel* channel() { return channel_.get(); } + + // Safe to call on any thread, as long as it's guaranteed that the thread's + // lifetime is less than the main thread. + IPC::SyncMessageFilter* sync_message_filter() { return sync_message_filter_; } + + private: + // IPC::Listener implementation. + virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnChannelError() OVERRIDE; + + // IPC message handlers. + void OnPbufferHandle(const std::string& todo); + + // Helper method to create the sync channel. + void CreateChannel(); + + bool client_connected_; + + IPC::ChannelHandle channel_handle_; + scoped_ptr<IPC::SyncChannel> channel_; + + // Allows threads other than the main thread to send sync messages. + scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_; + + DISALLOW_COPY_AND_ASSIGN(ViewerIPCServer); +}; + +#endif // UI_VIEWER_VIEWER_IPC_SERVER_H_ diff --git a/ui/viewer/viewer_main.cc b/ui/viewer/viewer_main.cc new file mode 100644 index 0000000..e49dcc0 --- /dev/null +++ b/ui/viewer/viewer_main.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2012 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/command_line.h" +#include "base/debug/debugger.h" +#include "base/message_loop.h" +#include "ui/compositor/test/compositor_test_support.h" +#include "ui/viewer/viewer_process.h" + +// Mainline routine for running as the viewer process. +int ViewerProcessMain() { + MessageLoop main_message_loop(MessageLoop::TYPE_UI); + ui::CompositorTestSupport::Initialize(); + + main_message_loop.set_thread_name("MainThread"); + CommandLine* command_line = CommandLine::ForCurrentProcess(); + + VLOG(1) << "Viewer process launched: " + << CommandLine::ForCurrentProcess()->GetCommandLineString(); + + base::PlatformThread::SetName("CrViewerMain"); + + // TODO(scottmg): Uniquize this process? + + ViewerProcess viewer_process; + if (viewer_process.Initialize(&main_message_loop, *command_line)) { + MessageLoopForUI::current()->Run(); + } else { + LOG(ERROR) << "Viewer process failed to initialize"; + } + viewer_process.Teardown(); + return 0; +} diff --git a/ui/viewer/viewer_message_generator.cc b/ui/viewer/viewer_message_generator.cc new file mode 100644 index 0000000..8c72a94 --- /dev/null +++ b/ui/viewer/viewer_message_generator.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2012 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. + +// Get basic type definitions. +#define IPC_MESSAGE_IMPL +#include "ui/viewer/viewer_message_generator.h" + +// Generate constructors. +#include "ipc/struct_constructor_macros.h" +#include "ui/viewer/viewer_message_generator.h" + +// Generate destructors. +#include "ipc/struct_destructor_macros.h" +#include "ui/viewer/viewer_message_generator.h" + +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" +namespace IPC { +#include "ui/viewer/viewer_message_generator.h" +} // namespace IPC + +// Generate param traits read methods. +#include "ipc/param_traits_read_macros.h" +namespace IPC { +#include "ui/viewer/viewer_message_generator.h" +} // namespace IPC + +// Generate param traits log methods. +#include "ipc/param_traits_log_macros.h" +namespace IPC { +#include "ui/viewer/viewer_message_generator.h" +} // namespace IPC diff --git a/ui/viewer/viewer_message_generator.h b/ui/viewer/viewer_message_generator.h new file mode 100644 index 0000000..579c08d --- /dev/null +++ b/ui/viewer/viewer_message_generator.h @@ -0,0 +1,7 @@ +// Copyright (c) 2012 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. + +// Multiply-included file, hence no include guard. + +#include "ui/viewer/viewer_messages.h" diff --git a/ui/viewer/viewer_messages.h b/ui/viewer/viewer_messages.h new file mode 100644 index 0000000..a5923c1 --- /dev/null +++ b/ui/viewer/viewer_messages.h @@ -0,0 +1,26 @@ +// Copyright (c) 2012 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. + +// Multiply-included message file, no traditional include guard. +#include <string> + +#include "ipc/ipc_channel_handle.h" +#include "ipc/ipc_message_macros.h" + +#define IPC_MESSAGE_START ViewerMsgStart + +//----------------------------------------------------------------------------- +// Viewer process messages: +// These are messages from the browser to the viewer process. + +// Shares the rendering handle to the viewer process. +IPC_MESSAGE_CONTROL1(ViewerMsg_PbufferHandle, + std::string /* TODO(scottmg): whatever type */) + +//----------------------------------------------------------------------------- +// Viewer process host messages: +// These are messages from the viewer process to the browser. + +// Connect to the browser (request a pbuffer handle). +IPC_MESSAGE_CONTROL0(ViewerHostMsg_Connect) diff --git a/ui/viewer/viewer_process.cc b/ui/viewer/viewer_process.cc new file mode 100644 index 0000000..9440aeb --- /dev/null +++ b/ui/viewer/viewer_process.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2012 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 "ui/viewer/viewer_process.h" + +#include "ui/viewer/viewer_ipc_server.h" +#include "ui/viewer/viewer_host_win.h" + +ViewerProcess* g_viewer_process = NULL; + +ViewerProcess::ViewerProcess() + : shutdown_event_(true, false), + main_message_loop_(NULL) { + DCHECK(!g_viewer_process); + g_viewer_process = this; +} + +ViewerProcess::~ViewerProcess() { + Teardown(); + g_viewer_process = NULL; +} + +bool ViewerProcess::Initialize(MessageLoop* message_loop, + const CommandLine& command_line) { + main_message_loop_ = message_loop; + + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + io_thread_.reset(new base::Thread("ViewerProcess_IO")); + if (!io_thread_->StartWithOptions(options)) { + NOTREACHED(); + Teardown(); + return false; + } + + VLOG(1) << "Starting Viewer Process IPC Server"; + // TODO(scottmg): Channel name should be per user-data-dir. + ipc_server_.reset(new ViewerIPCServer("viewer_ipc")); + ipc_server_->Init(); + + // TODO(scottmg): I guess the whole thing should be made Windows-only at + // some point. +#if defined(OS_WIN) + viewer_host_win_.reset(new ViewerHostWin); +#endif + + // TODO(scottmg): Ask for a handle here, maybe start a browser, all that + // jazz. + + return true; +} + +bool ViewerProcess::Teardown() { + ipc_server_.reset(); + io_thread_.reset(); + return true; +} + +bool ViewerProcess::HandleClientDisconnect() { + Terminate(); + return false; +} + +void ViewerProcess::Terminate() { + main_message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); +} diff --git a/ui/viewer/viewer_process.h b/ui/viewer/viewer_process.h new file mode 100644 index 0000000..6e80620 --- /dev/null +++ b/ui/viewer/viewer_process.h @@ -0,0 +1,69 @@ +// Copyright (c) 2012 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 UI_VIEWER_VIEWER_PROCESS_H_ +#define UI_VIEWER_VIEWER_PROCESS_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop_proxy.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" + +class CommandLine; +class ViewerHostWin; +class ViewerIPCServer; + +// The ViewerProcess does not inherit from ChildProcess because this +// process can live independently of the browser process. +class ViewerProcess { + public: + ViewerProcess(); + virtual ~ViewerProcess(); + + // Initialize the ViewerProcess with the message loop that it should run on. + // ViewerProcess takes ownership of |state|. + bool Initialize(MessageLoop* message_loop, const CommandLine& command_line); + + bool Teardown(); + + // Returns the message loop that we perform I/O coordination on (network + // requests, communication with renderers, etc.). + scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() { + return io_thread_->message_loop_proxy(); + } + + // A global event object that is signalled when the main thread's message + // loop exits. This gives background threads a way to observe the main + // thread shutting down. + base::WaitableEvent* shutdown_event() { + return &shutdown_event_; + } + + // Called by the IPC server when a client disconnects. A return value of + // true indicates that the IPC server should continue listening for new + // connections. + bool HandleClientDisconnect(); + + void Terminate(); + + private: + scoped_ptr<base::Thread> io_thread_; + scoped_ptr<ViewerIPCServer> ipc_server_; + + // An event that will be signalled when we shutdown. + base::WaitableEvent shutdown_event_; + + // Window that we draw into. + scoped_ptr<ViewerHostWin> viewer_host_win_; + + // Pointer to the main message loop that host this object. + MessageLoop* main_message_loop_; + + DISALLOW_COPY_AND_ASSIGN(ViewerProcess); +}; + +extern ViewerProcess* g_viewer_process; + +#endif // UI_VIEWER_VIEWER_PROCESS_H_ |