diff options
author | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 21:25:12 +0000 |
---|---|---|
committer | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 21:25:12 +0000 |
commit | 56deedeafb9d4880280e33a4d35e769a4c119cf2 (patch) | |
tree | 54fc3c6b34e33dc4ade1c11c3355d39e52b1563c | |
parent | 9d68072cff1c7d2e94ea2d35026f5cdd0736a3de (diff) | |
download | chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.zip chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.tar.gz chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.tar.bz2 |
Listen in the browser for a connection from a metro viewer process.
Render to the surface it provides to us.
BUG=151718
Review URL: https://codereview.chromium.org/10984007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159559 0039d316-1c4b-4281-b951-d872f2087c98
28 files changed, 405 insertions, 475 deletions
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 8a5295b..23d5009 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc @@ -49,6 +49,10 @@ #include "ui/base/win/message_box_win.h" #include "ui/gfx/platform_font_win.h" +#if defined(USE_AURA) +#include "chrome/browser/metro_viewer/metro_viewer_process_host_win.h" +#endif + namespace { @@ -211,6 +215,9 @@ void ChromeBrowserMainPartsWin::PreMainMessageLoopRun() { ChromeBrowserMainParts::PreMainMessageLoopRun(); removable_device_notifications_window_->Init(); +#if defined(USE_AURA) + metro_viewer_process_host_.reset(new MetroViewerProcessHost); +#endif } // static diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h index 4256382..4094013 100644 --- a/chrome/browser/chrome_browser_main_win.h +++ b/chrome/browser/chrome_browser_main_win.h @@ -11,6 +11,7 @@ #include "chrome/browser/chrome_browser_main.h" class CommandLine; +class MetroViewerProcessHost; namespace chrome { class RemovableDeviceNotificationsWindowWin; @@ -69,6 +70,9 @@ class ChromeBrowserMainPartsWin : public ChromeBrowserMainParts { private: scoped_refptr<chrome::RemovableDeviceNotificationsWindowWin> removable_device_notifications_window_; +#if defined(USE_AURA) + scoped_ptr<MetroViewerProcessHost> metro_viewer_process_host_; +#endif DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsWin); }; diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc b/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc new file mode 100644 index 0000000..bfbfe5f --- /dev/null +++ b/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc @@ -0,0 +1,55 @@ +// Copyright 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 "chrome/browser/metro_viewer/metro_viewer_process_host_win.h" + +#include "base/logging.h" +#include "content/public/browser/browser_thread.h" +#include "ipc/ipc_channel_proxy.h" +#include "ui/metro_viewer/metro_viewer_messages.h" +#include "ui/surface/accelerated_surface_win.h" + +MetroViewerProcessHost::MetroViewerProcessHost() { + channel_.reset(new IPC::ChannelProxy( + // TODO(scottmg): Need to have a secure way to randomize and request + // this name from the viewer-side. + "viewer", + IPC::Channel::MODE_NAMED_SERVER, + this, + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO))); +} + +MetroViewerProcessHost::~MetroViewerProcessHost() { +} + +bool MetroViewerProcessHost::Send(IPC::Message* msg) { + return channel_->Send(msg); +} + +bool MetroViewerProcessHost::OnMessageReceived(const IPC::Message& message) { + DCHECK(CalledOnValidThread()); + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(MetroViewerProcessHost, message) + IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetTargetSurface, OnSetTargetSurface) + IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MouseEvent, OnMouseEvent) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void MetroViewerProcessHost::OnSetTargetSurface( + gfx::NativeViewId target_surface) { + DLOG(INFO) << __FUNCTION__ << ", target_surface = " << target_surface; + HWND hwnd = reinterpret_cast<HWND>(target_surface); + + scoped_refptr<AcceleratedPresenter> any_window = + AcceleratedPresenter::GetForWindow(NULL); + any_window->SetNewTargetWindow(hwnd); +} + +void MetroViewerProcessHost::OnMouseEvent( + int msg, WPARAM w_param, LPARAM l_param) { + // TODO(scottmg): Pass to window. +} diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.h b/chrome/browser/metro_viewer/metro_viewer_process_host_win.h new file mode 100644 index 0000000..076d61b --- /dev/null +++ b/chrome/browser/metro_viewer/metro_viewer_process_host_win.h @@ -0,0 +1,41 @@ +// Copyright 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 CHROME_BROWSER_METRO_VIEWER_METRO_VIEWER_PROCESS_HOST_WIN_H_ +#define CHROME_BROWSER_METRO_VIEWER_METRO_VIEWER_PROCESS_HOST_WIN_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "ipc/ipc_listener.h" +#include "ipc/ipc_sender.h" +#include "ui/gfx/native_widget_types.h" + +namespace IPC { +class ChannelProxy; +} + +class MetroViewerProcessHost : public IPC::Listener, + public IPC::Sender, + public base::NonThreadSafe { + public: + MetroViewerProcessHost(); + virtual ~MetroViewerProcessHost(); + + // IPC::Sender implementation. + virtual bool Send(IPC::Message* msg) OVERRIDE; + + // IPC::Listener implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + private: + void OnSetTargetSurface(gfx::NativeViewId target_surface); + void OnMouseEvent(int msg, WPARAM w_param, LPARAM l_param); + + scoped_ptr<IPC::ChannelProxy> channel_; + + DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost); +}; + +#endif // CHROME_BROWSER_METRO_VIEWER_METRO_VIEWER_PROCESS_HOST_WIN_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 44ce739..d6493b53 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2339,6 +2339,10 @@ ['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.cc'], ['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.h'], ], + 'sources': [ + 'browser/metro_viewer/metro_viewer_process_host_win.cc', + 'browser/metro_viewer/metro_viewer_process_host_win.h', + ], 'dependencies': [ '../ui/aura/aura.gyp:aura', '../ui/compositor/compositor.gyp:compositor', @@ -2350,6 +2354,9 @@ ['exclude', '^browser/lifetime/application_lifetime_win.cc'], ['exclude', '^browser/fullscreen_win.cc'], ], + 'dependencies': [ + '../ui/metro_viewer/metro_viewer.gyp:metro_viewer', + ], }], ], }], diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index ca4e5f8..9416fe5 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h @@ -106,7 +106,7 @@ enum IPCMessageStart { BrowserPluginMsgStart, HyphenatorMsgStart, AndroidWebViewMsgStart, - ViewerMsgStart, + MetroViewerMsgStart, CCMsgStart, LastIPCMsgStart // Must come last. }; diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index d53f46a..07daf50 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -219,7 +219,6 @@ '../compositor/compositor.gyp:compositor_test_support', '../ui.gyp:ui', '../ui.gyp:ui_resources', - '../viewer/viewer.gyp:viewer', '../../ipc/ipc.gyp:ipc', 'aura', ], diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc index 6a6d43b..e30b2e4 100644 --- a/ui/aura/demo/demo_main.cc +++ b/ui/aura/demo/demo_main.cc @@ -27,8 +27,6 @@ #include "base/message_pump_aurax11.h" #endif -extern int ViewerProcessMain(); - namespace { // Trivial WindowDelegate implementation that draws a colored background. @@ -163,15 +161,6 @@ int DemoMain() { return 0; } -int RunMain() { - // TODO(scottmg): Something not crappy. - if (CommandLine::ForCurrentProcess()->HasSwitch("viewer")) { - return ViewerProcessMain(); - } else { - return DemoMain(); - } -} - } // namespace int main(int argc, char** argv) { @@ -184,5 +173,5 @@ int main(int argc, char** argv) { icu_util::Initialize(); ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); - return RunMain(); + return DemoMain(); } diff --git a/ui/viewer/viewer.gyp b/ui/metro_viewer/metro_viewer.gyp index 750b583..a9436d6 100644 --- a/ui/viewer/viewer.gyp +++ b/ui/metro_viewer/metro_viewer.gyp @@ -8,22 +8,16 @@ }, 'targets': [ { - 'target_name': 'viewer', + 'target_name': 'metro_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', + 'metro_viewer_message_generator.cc', + 'metro_viewer_message_generator.h', + 'metro_viewer_messages.h', ], 'include_dirs': [ '..', diff --git a/ui/viewer/viewer_message_generator.cc b/ui/metro_viewer/metro_viewer_message_generator.cc index 8c72a94..360321c 100644 --- a/ui/viewer/viewer_message_generator.cc +++ b/ui/metro_viewer/metro_viewer_message_generator.cc @@ -4,30 +4,30 @@ // Get basic type definitions. #define IPC_MESSAGE_IMPL -#include "ui/viewer/viewer_message_generator.h" +#include "ui/metro_viewer/metro_viewer_message_generator.h" // Generate constructors. #include "ipc/struct_constructor_macros.h" -#include "ui/viewer/viewer_message_generator.h" +#include "ui/metro_viewer/metro_viewer_message_generator.h" // Generate destructors. #include "ipc/struct_destructor_macros.h" -#include "ui/viewer/viewer_message_generator.h" +#include "ui/metro_viewer/metro_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" +#include "ui/metro_viewer/metro_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" +#include "ui/metro_viewer/metro_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" +#include "ui/metro_viewer/metro_viewer_message_generator.h" } // namespace IPC diff --git a/ui/viewer/viewer_message_generator.h b/ui/metro_viewer/metro_viewer_message_generator.h index 579c08d..4ea8688 100644 --- a/ui/viewer/viewer_message_generator.h +++ b/ui/metro_viewer/metro_viewer_message_generator.h @@ -4,4 +4,4 @@ // Multiply-included file, hence no include guard. -#include "ui/viewer/viewer_messages.h" +#include "ui/metro_viewer/metro_viewer_messages.h" diff --git a/ui/metro_viewer/metro_viewer_messages.h b/ui/metro_viewer/metro_viewer_messages.h new file mode 100644 index 0000000..776e06b --- /dev/null +++ b/ui/metro_viewer/metro_viewer_messages.h @@ -0,0 +1,22 @@ +// Copyright 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 include guard. + +#include "base/basictypes.h" +#include "ipc/ipc_message_macros.h" +#include "ui/gfx/native_widget_types.h" + +#define IPC_MESSAGE_START MetroViewerMsgStart + +// Messages sent from the viewer to the browser. + +// Inform the browser of the surface to target for compositing. +IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_SetTargetSurface, + gfx::NativeViewId /* target hwnd */) + +IPC_MESSAGE_CONTROL3(MetroViewerHostMsg_MouseEvent, + int, /* msg */ + uintptr_t, /* message's wParam */ + intptr_t /* message's lParam */) diff --git a/ui/surface/accelerated_surface_win.cc b/ui/surface/accelerated_surface_win.cc index 1e72d9a..ded05b4 100644 --- a/ui/surface/accelerated_surface_win.cc +++ b/ui/surface/accelerated_surface_win.cc @@ -412,6 +412,10 @@ void AcceleratedPresenterMap::RemovePresenter( scoped_refptr<AcceleratedPresenter> AcceleratedPresenterMap::GetPresenter( gfx::PluginWindowHandle window) { base::AutoLock locked(lock_); + + if (!window) + return presenters_.begin()->second; + PresenterMap::iterator it = presenters_.find(window); if (it == presenters_.end()) return scoped_refptr<AcceleratedPresenter>(); @@ -661,6 +665,12 @@ void AcceleratedPresenter::Invalidate() { window_ = NULL; } +#if defined(USE_AURA) +void AcceleratedPresenter::SetNewTargetWindow(gfx::PluginWindowHandle window) { + window_ = window; +} +#endif + AcceleratedPresenter::~AcceleratedPresenter() { } diff --git a/ui/surface/accelerated_surface_win.h b/ui/surface/accelerated_surface_win.h index d228249..20c8f9e 100644 --- a/ui/surface/accelerated_surface_win.h +++ b/ui/surface/accelerated_surface_win.h @@ -63,6 +63,12 @@ class SURFACE_EXPORT AcceleratedPresenter void* buf); void Invalidate(); +#if defined(USE_AURA) + // TODO(scottmg): This is a temporary hack until we have a two-worlds ash/aura + // separation. + void SetNewTargetWindow(gfx::PluginWindowHandle window); +#endif + private: friend class base::RefCountedThreadSafe<AcceleratedPresenter>; diff --git a/ui/viewer/viewer_host_win.cc b/ui/viewer/viewer_host_win.cc deleted file mode 100644 index fe21c55..0000000 --- a/ui/viewer/viewer_host_win.cc +++ /dev/null @@ -1,53 +0,0 @@ -// 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 deleted file mode 100644 index 57da87e..0000000 --- a/ui/viewer/viewer_host_win.h +++ /dev/null @@ -1,36 +0,0 @@ -// 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 deleted file mode 100644 index 578d193..0000000 --- a/ui/viewer/viewer_ipc_server.cc +++ /dev/null @@ -1,98 +0,0 @@ -// 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 deleted file mode 100644 index 8ab2bd0..0000000 --- a/ui/viewer/viewer_ipc_server.h +++ /dev/null @@ -1,57 +0,0 @@ -// 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 deleted file mode 100644 index e49dcc0..0000000 --- a/ui/viewer/viewer_main.cc +++ /dev/null @@ -1,34 +0,0 @@ -// 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_messages.h b/ui/viewer/viewer_messages.h deleted file mode 100644 index a5923c1..0000000 --- a/ui/viewer/viewer_messages.h +++ /dev/null @@ -1,26 +0,0 @@ -// 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 deleted file mode 100644 index 9440aeb..0000000 --- a/ui/viewer/viewer_process.cc +++ /dev/null @@ -1,67 +0,0 @@ -// 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 deleted file mode 100644 index 6e80620..0000000 --- a/ui/viewer/viewer_process.h +++ /dev/null @@ -1,69 +0,0 @@ -// 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_ diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc index 4f57a82..05308a0 100644 --- a/win8/delegate_execute/command_execute_impl.cc +++ b/win8/delegate_execute/command_execute_impl.cc @@ -138,6 +138,12 @@ STDMETHODIMP CommandExecuteImpl::GetValue(enum AHE_TYPE* pahe) { return S_OK; } + if (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_F11)) { + AtlTrace("Using Shift-F11 debug hook, returning AHE_IMMERSIVE\n"); + *pahe = AHE_IMMERSIVE; + return S_OK; + } + FilePath user_data_dir; if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { AtlTrace("Failed to get chrome's data dir path, E_FAIL\n"); diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc index abac4b5..71392d0 100644 --- a/win8/metro_driver/chrome_app_view.cc +++ b/win8/metro_driver/chrome_app_view.cc @@ -4,6 +4,7 @@ #include "win8/metro_driver/stdafx.h" #include "win8/metro_driver/chrome_app_view.h" +#include "win8/metro_driver/direct3d_helper.h" #include <algorithm> #include <windows.applicationModel.datatransfer.h> @@ -13,11 +14,19 @@ #include "base/message_loop.h" #include "base/win/metro.h" +#include "base/threading/thread.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_sender.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/metro_viewer/metro_viewer_messages.h" + // This include allows to send WM_SYSCOMMANDs to chrome. #include "chrome/app/chrome_command_ids.h" #include "win8/metro_driver/winrt_utils.h" #include "ui/base/ui_base_switches.h" + typedef winfoundtn::ITypedEventHandler< winapp::Core::CoreApplicationView*, winapp::Activation::IActivatedEventArgs*> ActivatedHandler; @@ -282,6 +291,26 @@ void FlipFrameWindowsInternal() { } } +class ChromeChannelListener : public IPC::Listener { + public: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { + DVLOG(1) << "Received ipc message " << message.type(); + return true; + } + + virtual void OnChannelError() OVERRIDE { + DVLOG(1) << "Channel error"; + MessageLoop::current()->Quit(); + } + + void Init(IPC::Sender* s) { + sender_ = s; + } + + private: + IPC::Sender* sender_; +}; + } // namespace HRESULT ChromeAppView::TileRequestCreateDone( @@ -715,6 +744,10 @@ ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { DVLOG(1) << "Created appview instance."; + direct3d_helper_.Initialize(window); + + DVLOG(1) << "Initialized Direct3D."; + hr = devices_handler_.Initialize(window); // Don't check or return the failure here, we need to let the app // initialization succeed. Even if we won't be able to access devices @@ -786,7 +819,7 @@ void ChromeAppView::CheckForOSKActivation() { IFACEMETHODIMP ChromeAppView::Run() { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(window_.Get()); + DVLOG(1) << __FUNCTION__; mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; HRESULT hr = window_->get_Dispatcher(&dispatcher); CheckHR(hr, "Dispatcher failed."); @@ -804,6 +837,21 @@ ChromeAppView::Run() { // Announce our message loop to the world. globals.appview_msg_loop = msg_loop.message_loop_proxy(); + // The thread needs to out-live the ChannelProxy. + base::Thread thread("metro_IO_thread"); + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + thread.StartWithOptions(options); + + ChromeChannelListener channel_listener; + IPC::ChannelProxy chan("viewer", IPC::Channel::MODE_NAMED_CLIENT, + &channel_listener, thread.message_loop_proxy()); + channel_listener.Init(&chan); + chan.Send(new MetroViewerHostMsg_SetTargetSurface( + gfx::NativeViewId(globals.core_window))); + + DVLOG(1) << "ICoreWindow sent " << globals.core_window; + // And post the task that'll do the inner Metro message pumping to it. msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); @@ -912,17 +960,20 @@ HRESULT ChromeAppView::OnActivate(winapp::Core::ICoreApplicationView*, DVLOG(1) << "CoreWindow found: " << std::hex << globals.core_window; + +#if !defined(USE_AURA) if (!globals.host_thread) { DWORD chrome_ui_thread_id = 0; globals.host_thread = ::CreateThread(NULL, 0, HostMainThreadProc, NULL, 0, - &chrome_ui_thread_id); + &chrome_ui_thread_id); if (!globals.host_thread) { NOTREACHED() << "thread creation failed."; return E_UNEXPECTED; } } +#endif if (RegisterHotKey(globals.core_window, kFlipWindowsHotKeyId, MOD_CONTROL, VK_F12)) { diff --git a/win8/metro_driver/chrome_app_view.h b/win8/metro_driver/chrome_app_view.h index 80f309d..cca7864 100644 --- a/win8/metro_driver/chrome_app_view.h +++ b/win8/metro_driver/chrome_app_view.h @@ -20,6 +20,7 @@ #include "base/synchronization/lock.h" #include "win8/metro_driver/chrome_url_launch_handler.h" #include "win8/metro_driver/devices_handler.h" +#include "win8/metro_driver/direct3d_helper.h" #include "win8/metro_driver/metro_dialog_box.h" #include "win8/metro_driver/settings_handler.h" #include "win8/metro_driver/toast_notification_handler.h" @@ -132,6 +133,8 @@ class ChromeAppView int osk_offset_adjustment_; MetroDialogBox dialog_box_; + + metro_driver::Direct3DHelper direct3d_helper_; }; class ChromeAppViewFactory diff --git a/win8/metro_driver/direct3d_helper.cc b/win8/metro_driver/direct3d_helper.cc new file mode 100644 index 0000000..a4c3201 --- /dev/null +++ b/win8/metro_driver/direct3d_helper.cc @@ -0,0 +1,128 @@ +// Copyright 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 "stdafx.h" +#include "win8/metro_driver/direct3d_helper.h" +#include "win8/metro_driver/winrt_utils.h" + +#include "base/logging.h" + +#include <windows.graphics.display.h> + +namespace { + +void CheckIfFailed(HRESULT hr) { + DCHECK(!FAILED(hr)); + if (FAILED(hr)) + DVLOG(ERROR) << "Direct3D call failed, hr = " << hr; +} + +float GetLogicalDpi() { + mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; + CheckIfFailed(winrt_utils::CreateActivationFactory( + RuntimeClass_Windows_Graphics_Display_DisplayProperties, + display_properties.GetAddressOf())); + float dpi = 0.0; + CheckIfFailed(display_properties->get_LogicalDpi(&dpi)); + return dpi; +} + +float ConvertDipsToPixels(float dips) { + static const float dips_per_inch = 96.f; + float logical_dpi = GetLogicalDpi(); + return floor(dips * logical_dpi / dips_per_inch + 0.5f); +} + +} + +namespace metro_driver { + +Direct3DHelper::Direct3DHelper() { +} + +Direct3DHelper::~Direct3DHelper() { +} + +void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) { + window_ = window; + CreateDeviceResources(); + CreateWindowSizeDependentResources(); +} + +// TODO(scottmg): Need to handle resize messages and recreation. + +void Direct3DHelper::CreateDeviceResources() { + unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + D3D_FEATURE_LEVEL feature_levels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, + }; + + mswr::ComPtr<ID3D11Device> device; + mswr::ComPtr<ID3D11DeviceContext> context; + CheckIfFailed( + D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_HARDWARE, + nullptr, + creation_flags, + feature_levels, + ARRAYSIZE(feature_levels), + D3D11_SDK_VERSION, + &device, + &feature_level_, + &context)); + CheckIfFailed(device.As(&d3d_device_)); + CheckIfFailed(context.As(&d3d_context_)); +} + +void Direct3DHelper::CreateWindowSizeDependentResources() { + CheckIfFailed(window_->get_Bounds(&window_bounds_)); + float window_width = ConvertDipsToPixels(window_bounds_.Width); + float window_height = ConvertDipsToPixels(window_bounds_.Height); + + // TODO(scottmg): Orientation. + + if (swap_chain_ != nullptr) { + // TODO(scottmg): Resize if it already exists. + NOTIMPLEMENTED(); + } else { + DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 }; + swap_chain_desc.Width = window_width; + swap_chain_desc.Height = window_height; + swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swap_chain_desc.Stereo = false; + swap_chain_desc.SampleDesc.Count = 1; + swap_chain_desc.SampleDesc.Quality = 0; + swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain_desc.BufferCount = 2; // TODO(scottmg): Probably 1 is fine. + swap_chain_desc.Scaling = DXGI_SCALING_NONE; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swap_chain_desc.Flags = 0; + + mswr::ComPtr<IDXGIDevice1> dxgi_device; + CheckIfFailed(d3d_device_.As(&dxgi_device)); + + mswr::ComPtr<IDXGIAdapter> dxgi_adapter; + CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter)); + + mswr::ComPtr<IDXGIFactory2> dxgi_factory; + CheckIfFailed(dxgi_adapter->GetParent( + __uuidof(IDXGIFactory2), &dxgi_factory)); + + CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow( + d3d_device_.Get(), + reinterpret_cast<IUnknown*>(window_), + &swap_chain_desc, + nullptr, + &swap_chain_)); + } +} + +} // namespace metro_driver diff --git a/win8/metro_driver/direct3d_helper.h b/win8/metro_driver/direct3d_helper.h new file mode 100644 index 0000000..a5547ba --- /dev/null +++ b/win8/metro_driver/direct3d_helper.h @@ -0,0 +1,44 @@ +// Copyright 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 WIN8_METRO_DRIVER_DIRECT3D_HELPER_ +#define WIN8_METRO_DRIVER_DIRECT3D_HELPER_ + +#include "base/basictypes.h" + +#include <windows.ui.core.h> +#include <windows.foundation.h> +#include <d3d11_1.h> + +namespace metro_driver { + +// We need to initalize a Direct3D device and swapchain so that the browser +// can Present to our HWND. This class takes care of creating and keeping the +// swapchain up to date. +class Direct3DHelper { + public: + Direct3DHelper(); + ~Direct3DHelper(); + + void Initialize(winui::Core::ICoreWindow* window); + + private: + void CreateDeviceResources(); + void CreateWindowSizeDependentResources(); + + winui::Core::ICoreWindow* window_; + + mswr::ComPtr<ID3D11Device1> d3d_device_; + mswr::ComPtr<ID3D11DeviceContext1> d3d_context_; + mswr::ComPtr<IDXGISwapChain1> swap_chain_; + D3D_FEATURE_LEVEL feature_level_; + + ABI::Windows::Foundation::Rect window_bounds_; + + DISALLOW_COPY_AND_ASSIGN(Direct3DHelper); +}; + +} // namespace metro_driver + +#endif // WIN8_METRO_DRIVER_DIRECT3D_HELPER_ diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index 94960cdf..e8f6481 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -31,10 +31,12 @@ 'type': 'shared_library', 'dependencies': [ '../../base/base.gyp:base', - '../../build/temp_gyp/googleurl.gyp:googleurl', + '../../build/temp_gyp/googleurl.gyp:googleurl', '../../crypto/crypto.gyp:crypto', - '../../sandbox/sandbox.gyp:sandbox', '../../google_update/google_update.gyp:google_update', + '../../ipc/ipc.gyp:ipc', + '../../sandbox/sandbox.gyp:sandbox', + '../../ui/metro_viewer/metro_viewer.gyp:metro_viewer', '../win8.gyp:check_sdk_patch', ], 'sources': [ @@ -46,6 +48,8 @@ '../delegate_execute/chrome_util.h', 'devices_handler.cc', 'devices_handler.h', + 'direct3d_helper.cc', + 'direct3d_helper.h', 'file_picker.h', 'file_picker.cc', 'metro_dialog_box.cc', |