diff options
-rw-r--r-- | ash/ash.gyp | 5 | ||||
-rw-r--r-- | ash/test/DEPS | 1 | ||||
-rw-r--r-- | ash/test/ash_test_base.cc | 9 | ||||
-rw-r--r-- | ash/test/ash_test_base.h | 4 | ||||
-rw-r--r-- | ash/test/test_metro_viewer_process_host.cc | 73 | ||||
-rw-r--r-- | ash/test/test_metro_viewer_process_host.h | 58 | ||||
-rw-r--r-- | chrome/browser/DEPS | 1 | ||||
-rw-r--r-- | chrome/browser/browser_process_platform_part_aurawin.cc | 4 | ||||
-rw-r--r-- | chrome/browser/browser_process_platform_part_aurawin.h | 4 | ||||
-rw-r--r-- | chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc (renamed from chrome/browser/metro_viewer/metro_viewer_process_host_win.cc) | 48 | ||||
-rw-r--r-- | chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h | 24 | ||||
-rw-r--r-- | chrome/browser/metro_viewer/metro_viewer_process_host_win.h | 47 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 9 | ||||
-rw-r--r-- | ui/aura/aura.gyp | 4 | ||||
-rw-r--r-- | ui/metro_viewer/metro_viewer.gyp | 3 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.gyp | 2 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 108 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 94 | ||||
-rw-r--r-- | win8/win8.gyp | 14 |
19 files changed, 289 insertions, 223 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 05d2788..90df2f0 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -575,9 +575,10 @@ ['OS=="win"', { 'dependencies': [ '../ipc/ipc.gyp:ipc', - '../ui/metro_viewer/metro_viewer.gyp:metro_viewer', - '../win8/win8_tests.gyp:test_registrar', + '../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', + '../win8/win8.gyp:metro_viewer', '../win8/win8.gyp:test_support_win8', + '../win8/win8_tests.gyp:test_registrar', ], 'sources': [ 'test/test_metro_viewer_process_host.cc', diff --git a/ash/test/DEPS b/ash/test/DEPS index ace334c..8bc7896 100644 --- a/ash/test/DEPS +++ b/ash/test/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+content/public/test", "+content/test", + "+win8/viewer", ] diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 99105e1..87f2243 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc @@ -119,7 +119,14 @@ void AshTestBase::SetUp() { if (base::win::GetVersion() >= base::win::VERSION_WIN8 && !CommandLine::ForCurrentProcess()->HasSwitch( ash::switches::kForceAshToDesktop)) { - metro_viewer_host_.reset(new TestMetroViewerProcessHost("viewer")); + ipc_thread_.reset(new base::Thread("test_metro_viewer_ipc_thread")); + base::Thread::Options options; + options.message_loop_type = base::MessageLoop::TYPE_IO; + ipc_thread_->StartWithOptions(options); + + metro_viewer_host_.reset( + new TestMetroViewerProcessHost("viewer", + ipc_thread_->message_loop_proxy())); CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection( win8::test::kDefaultTestAppUserModelId)); aura::RemoteRootWindowHostWin* root_window_host = diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index dd65bf4..2d9f717 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/message_loop.h" +#include "base/threading/thread.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/client/window_types.h" @@ -109,6 +110,9 @@ class AshTestBase : public testing::Test { scoped_ptr<AshTestHelper> ash_test_helper_; scoped_ptr<aura::test::EventGenerator> event_generator_; #if defined(OS_WIN) + // Note that the order is important here as ipc_thread_ should be destroyed + // after metro_viewer_host_->channel_. + scoped_ptr<base::Thread> ipc_thread_; scoped_ptr<TestMetroViewerProcessHost> metro_viewer_host_; ui::ScopedOleInitializer ole_initializer_; #endif diff --git a/ash/test/test_metro_viewer_process_host.cc b/ash/test/test_metro_viewer_process_host.cc index 277864f..a5d36e9 100644 --- a/ash/test/test_metro_viewer_process_host.cc +++ b/ash/test/test_metro_viewer_process_host.cc @@ -23,81 +23,14 @@ namespace ash { namespace test { -TestMetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter( - TestMetroViewerProcessHost* owner) - : owner_(owner) { -} - -void TestMetroViewerProcessHost::InternalMessageFilter::OnChannelConnected( - int32 peer_pid) { - owner_->NotifyChannelConnected(); -} - TestMetroViewerProcessHost::TestMetroViewerProcessHost( - const std::string& ipc_channel_name) - : ipc_thread_("test_metro_viewer_ipc_thread"), - channel_connected_event_(false, false), + const std::string& ipc_channel_name, + base::SingleThreadTaskRunner* ipc_task_runner) + : MetroViewerProcessHost(ipc_channel_name, ipc_task_runner), closed_unexpectedly_(false) { - - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - ipc_thread_.StartWithOptions(options); - - channel_.reset(new IPC::ChannelProxy( - ipc_channel_name.c_str(), - IPC::Channel::MODE_NAMED_SERVER, - this, - ipc_thread_.message_loop_proxy())); - - channel_->AddFilter(new InternalMessageFilter(this)); } TestMetroViewerProcessHost::~TestMetroViewerProcessHost() { - channel_.reset(); - ipc_thread_.Stop(); -} - -void TestMetroViewerProcessHost::NotifyChannelConnected() { - channel_connected_event_.Signal(); -} - -bool TestMetroViewerProcessHost::LaunchViewerAndWaitForConnection( - const base::string16& app_user_model_id) { - // Activate the viewer process. NOTE: This assumes that the viewer process is - // registered as the default browser using the provided |app_user_model_id|. - - // TODO(robertshield): Initialize COM at test suite startup. - base::win::ScopedCOMInitializer com_initializer; - - base::win::ScopedComPtr<IApplicationActivationManager> activator; - HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); - if (SUCCEEDED(hr)) { - DWORD pid = 0; - hr = activator->ActivateApplication( - app_user_model_id.c_str(), L"open", AO_NONE, &pid); - } - - LOG_IF(ERROR, FAILED(hr)) << "Tried and failed to launch Metro Chrome. " - << "hr=" << std::hex << hr; - - // Having launched the viewer process, now we wait for it to connect. - return channel_connected_event_.TimedWait(base::TimeDelta::FromSeconds(60)); -} - -bool TestMetroViewerProcessHost::Send(IPC::Message* msg) { - return channel_->Send(msg); -} - -bool TestMetroViewerProcessHost::OnMessageReceived( - const IPC::Message& message) { - DCHECK(CalledOnValidThread()); - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(TestMetroViewerProcessHost, message) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetTargetSurface, OnSetTargetSurface) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled ? true : - aura::RemoteRootWindowHostWin::Instance()->OnMessageReceived(message); } void TestMetroViewerProcessHost::OnChannelError() { diff --git a/ash/test/test_metro_viewer_process_host.h b/ash/test/test_metro_viewer_process_host.h index f52230b..0f24169 100644 --- a/ash/test/test_metro_viewer_process_host.h +++ b/ash/test/test_metro_viewer_process_host.h @@ -7,69 +7,25 @@ #include <string> -#include "base/memory/scoped_ptr.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/non_thread_safe.h" -#include "base/threading/thread.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_listener.h" -#include "ipc/ipc_sender.h" -#include "ui/gfx/native_widget_types.h" +#include "win8/viewer/metro_viewer_process_host.h" class AcceleratedSurface; namespace ash { namespace test { -class TestMetroViewerProcessHost : public IPC::Listener, - public IPC::Sender, - public base::NonThreadSafe { +class TestMetroViewerProcessHost : public win8::MetroViewerProcessHost { public: - explicit TestMetroViewerProcessHost(const std::string& ipc_channel_name); + TestMetroViewerProcessHost(const std::string& ipc_channel_name, + base::SingleThreadTaskRunner* ipc_task_runner); virtual ~TestMetroViewerProcessHost(); - // Launches the viewer process associated with the given |app_user_model_id| - // and blocks until that viewer process connects or until a timeout is - // reached. Returns true if the viewer process connects before the timeout is - // reached. - bool LaunchViewerAndWaitForConnection( - const base::string16& app_user_model_id); - - // IPC::Sender implementation: - virtual bool Send(IPC::Message* msg) OVERRIDE; - - // IPC::Listener implementation: - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - bool closed_unexpectedly() { return closed_unexpectedly_; } private: - void OnSetTargetSurface(gfx::NativeViewId target_surface); - - void NotifyChannelConnected(); - - // Inner message filter used to handle connection event on the IPC channel - // proxy's background thread. This prevents consumers of - // TestMetroViewerProcessHost from having to pump messages on their own - // message loop. - class InternalMessageFilter : public IPC::ChannelProxy::MessageFilter { - public: - InternalMessageFilter(TestMetroViewerProcessHost* owner); - - // IPC::ChannelProxy::MessageFilter implementation. - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - - private: - TestMetroViewerProcessHost* owner_; - DISALLOW_COPY_AND_ASSIGN(InternalMessageFilter); - }; - - // Members related to the IPC channel. Note that the order is important - // here as ipc_thread_ should be destroyed after channel_. - base::Thread ipc_thread_; - scoped_ptr<IPC::ChannelProxy> channel_; - base::WaitableEvent channel_connected_event_; + // win8::MetroViewerProcessHost implementation + virtual void OnChannelError() OVERRIDE; + virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) OVERRIDE; scoped_ptr<AcceleratedSurface> backing_surface; diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 84d57983..3a00e5c 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -44,6 +44,7 @@ include_rules = [ "+sync/protocol", # Sync protobuf files. "+third_party/cros_system_api", "+win8/util", + "+win8/viewer", "+xib_localizers", # For generated mac localization helpers # TODO(stuartmorgan): Remove these by refactoring necessary code out of diff --git a/chrome/browser/browser_process_platform_part_aurawin.cc b/chrome/browser/browser_process_platform_part_aurawin.cc index f1730f9..e6be06d 100644 --- a/chrome/browser/browser_process_platform_part_aurawin.cc +++ b/chrome/browser/browser_process_platform_part_aurawin.cc @@ -9,7 +9,7 @@ #include "base/process_util.h" #include "base/win/windows_version.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/metro_viewer/metro_viewer_process_host_win.h" +#include "chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h" #include "chrome/common/chrome_switches.h" BrowserProcessPlatformPart::BrowserProcessPlatformPart() { @@ -29,7 +29,7 @@ void BrowserProcessPlatformPart::PlatformSpecificCommandLineProcessing( !metro_viewer_process_host_.get()) { // Tell the metro viewer process host to connect to the given IPC channel. metro_viewer_process_host_.reset( - new MetroViewerProcessHost( + new ChromeMetroViewerProcessHost( command_line.GetSwitchValueASCII(switches::kViewerConnection))); } } diff --git a/chrome/browser/browser_process_platform_part_aurawin.h b/chrome/browser/browser_process_platform_part_aurawin.h index b1b74a0..ef231c4 100644 --- a/chrome/browser/browser_process_platform_part_aurawin.h +++ b/chrome/browser/browser_process_platform_part_aurawin.h @@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/browser_process_platform_part_base.h" -class MetroViewerProcessHost; +class ChromeMetroViewerProcessHost; class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase { public: @@ -27,7 +27,7 @@ class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase { private: // Hosts the channel for the Windows 8 metro viewer process which runs in // the ASH environment. - scoped_ptr<MetroViewerProcessHost> metro_viewer_process_host_; + scoped_ptr<ChromeMetroViewerProcessHost> metro_viewer_process_host_; DISALLOW_COPY_AND_ASSIGN(BrowserProcessPlatformPart); }; diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc index b2c2d21..03385f7 100644 --- a/chrome/browser/metro_viewer/metro_viewer_process_host_win.cc +++ b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc @@ -2,9 +2,10 @@ // 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 "chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h" #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_aurawin.h" #include "chrome/browser/ui/ash/ash_init.h" @@ -17,9 +18,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" -#include "ipc/ipc_channel_proxy.h" #include "ui/aura/remote_root_window_host_win.h" -#include "ui/metro_viewer/metro_viewer_messages.h" #include "ui/surface/accelerated_surface_win.h" namespace { @@ -42,43 +41,16 @@ void CloseOpenAshBrowsers() { } // namespace - -MetroViewerProcessHost::MetroViewerProcessHost( - const std::string& ipc_channel_name) { +ChromeMetroViewerProcessHost::ChromeMetroViewerProcessHost( + const std::string& ipc_channel_name) + : MetroViewerProcessHost( + ipc_channel_name, + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)) { g_browser_process->AddRefModule(); - channel_.reset(new IPC::ChannelProxy( - ipc_channel_name.c_str(), - IPC::Channel::MODE_NAMED_SERVER, - this, - content::BrowserThread::GetMessageLoopProxyForThread( - content::BrowserThread::IO))); -} - -MetroViewerProcessHost::~MetroViewerProcessHost() { -} - -base::ProcessId MetroViewerProcessHost::GetViewerProcessId() { - if (channel_) - return channel_->peer_pid(); - return base::kNullProcessId; -} - -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_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled ? true : - aura::RemoteRootWindowHostWin::Instance()->OnMessageReceived(message); } -void MetroViewerProcessHost::OnChannelError() { +void ChromeMetroViewerProcessHost::OnChannelError() { // TODO(cpu): At some point we only close the browser. Right now this // is very convenient for developing. DLOG(INFO) << "viewer channel error : Quitting browser"; @@ -97,7 +69,7 @@ void MetroViewerProcessHost::OnChannelError() { g_browser_process->platform_part()->OnMetroViewerProcessTerminated(); } -void MetroViewerProcessHost::OnSetTargetSurface( +void ChromeMetroViewerProcessHost::OnSetTargetSurface( gfx::NativeViewId target_surface) { DLOG(INFO) << __FUNCTION__ << ", target_surface = " << target_surface; HWND hwnd = reinterpret_cast<HWND>(target_surface); diff --git a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h new file mode 100644 index 0000000..f3411c7 --- /dev/null +++ b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h @@ -0,0 +1,24 @@ +// 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_CHROME_METRO_VIEWER_PROCESS_HOST_AURAWIN_H_ +#define CHROME_BROWSER_METRO_VIEWER_CHROME_METRO_VIEWER_PROCESS_HOST_AURAWIN_H_ + +#include <string> + +#include "win8/viewer/metro_viewer_process_host.h" + +class ChromeMetroViewerProcessHost : public win8::MetroViewerProcessHost { + public: + explicit ChromeMetroViewerProcessHost(const std::string& ipc_channel_name); + + private: + // win8::MetroViewerProcessHost implementation + virtual void OnChannelError() OVERRIDE; + virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(ChromeMetroViewerProcessHost); +}; + +#endif // CHROME_BROWSER_METRO_VIEWER_CHROME_METRO_VIEWER_PROCESS_HOST_AURAWIN_H_ diff --git a/chrome/browser/metro_viewer/metro_viewer_process_host_win.h b/chrome/browser/metro_viewer/metro_viewer_process_host_win.h deleted file mode 100644 index 765877b..0000000 --- a/chrome/browser/metro_viewer/metro_viewer_process_host_win.h +++ /dev/null @@ -1,47 +0,0 @@ -// 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 <string> - -#include "base/memory/scoped_ptr.h" -#include "base/process_util.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: - explicit MetroViewerProcessHost(const std::string& ipc_channel_name); - virtual ~MetroViewerProcessHost(); - - // Returns the process id of the viewer process if one is connected to this - // host, returns base::kNullProcessId otherwise. - base::ProcessId GetViewerProcessId(); - - private: - // IPC::Sender implementation: - virtual bool Send(IPC::Message* msg) OVERRIDE; - - // IPC::Listener implementation: - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - - void OnSetTargetSurface(gfx::NativeViewId target_surface); - - 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 9192b78..dfcd360 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1094,6 +1094,8 @@ 'browser/metrics/variations/variations_request_scheduler_mobile.h', 'browser/metrics/variations/variations_service.cc', 'browser/metrics/variations/variations_service.h', + 'browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc', + 'browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h', 'browser/native_window_notification_source.h', 'browser/net/about_protocol_handler.cc', 'browser/net/about_protocol_handler.h', @@ -2636,10 +2638,6 @@ ['exclude', '^browser/lifetime/application_lifetime_stub.cc'], ['exclude', '^browser/renderer_host/render_widget_host_view_views*'], ], - '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', @@ -2654,7 +2652,8 @@ ], 'dependencies': [ 'launcher_support', - '../ui/metro_viewer/metro_viewer.gyp:metro_viewer', + '../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', + '../win8/win8.gyp:metro_viewer', ], }], ], diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index feab883..547b719 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -122,8 +122,8 @@ }], ['OS=="win"', { 'dependencies': [ - '../metro_viewer/metro_viewer.gyp:metro_viewer', - '../../ipc/ipc.gyp:ipc', + '../metro_viewer/metro_viewer.gyp:metro_viewer_messages', + '../../ipc/ipc.gyp:ipc', ], }], ], diff --git a/ui/metro_viewer/metro_viewer.gyp b/ui/metro_viewer/metro_viewer.gyp index a9436d6..00c3212 100644 --- a/ui/metro_viewer/metro_viewer.gyp +++ b/ui/metro_viewer/metro_viewer.gyp @@ -8,7 +8,7 @@ }, 'targets': [ { - 'target_name': 'metro_viewer', + 'target_name': 'metro_viewer_messages', 'type': 'static_library', 'dependencies': [ '../../base/base.gyp:base', @@ -25,4 +25,3 @@ }, ], } - diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index f1f9892..623b000 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -58,7 +58,7 @@ '../../google_update/google_update.gyp:google_update', '../../ipc/ipc.gyp:ipc', '../../sandbox/sandbox.gyp:sandbox', - '../../ui/metro_viewer/metro_viewer.gyp:metro_viewer', + '../../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', '../win8.gyp:check_sdk_patch', 'metro_driver_version_resources', ], diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc new file mode 100644 index 0000000..f945039 --- /dev/null +++ b/win8/viewer/metro_viewer_process_host.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2013 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 "win8/viewer/metro_viewer_process_host.h" + +#include <shlobj.h> + +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/process.h" +#include "base/string16.h" +#include "base/synchronization/waitable_event.h" +#include "base/time.h" +#include "base/win/scoped_comptr.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ui/aura/remote_root_window_host_win.h" +#include "ui/metro_viewer/metro_viewer_messages.h" + +namespace win8 { + +MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter( + MetroViewerProcessHost* owner) : owner_(owner) { +} + +void MetroViewerProcessHost::InternalMessageFilter::OnChannelConnected( + int32 /* peer_pid */) { + owner_->NotifyChannelConnected(); +} + +MetroViewerProcessHost::MetroViewerProcessHost( + const std::string& ipc_channel_name, + base::SingleThreadTaskRunner* ipc_task_runner) { + + channel_.reset(new IPC::ChannelProxy( + ipc_channel_name.c_str(), + IPC::Channel::MODE_NAMED_SERVER, + this, + ipc_task_runner)); +} + +MetroViewerProcessHost::~MetroViewerProcessHost() { +} + +base::ProcessId MetroViewerProcessHost::GetViewerProcessId() { + if (channel_) + return channel_->peer_pid(); + return base::kNullProcessId; +} + +bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection( + const base::string16& app_user_model_id) { + DCHECK_EQ(base::kNullProcessId, channel_->peer_pid()); + + channel_connected_event_.reset(new base::WaitableEvent(false, false)); + + scoped_refptr<InternalMessageFilter> message_filter( + new InternalMessageFilter(this)); + channel_->AddFilter(message_filter); + + base::win::ScopedComPtr<IApplicationActivationManager> activator; + HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); + if (SUCCEEDED(hr)) { + DWORD pid = 0; + hr = activator->ActivateApplication( + app_user_model_id.c_str(), L"open", AO_NONE, &pid); + } + + LOG_IF(ERROR, FAILED(hr)) << "Tried and failed to launch Metro Chrome. " + << "hr=" << std::hex << hr; + + // Having launched the viewer process, now we wait for it to connect. + bool success = + channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(60)); + channel_connected_event_.reset(); + + // |message_filter| is only used to signal |channel_connected_event_| above + // and can thus be removed after |channel_connected_event_| is no longer + // waiting. + channel_->RemoveFilter(message_filter); + return success; +} + +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_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled ? true : + aura::RemoteRootWindowHostWin::Instance()->OnMessageReceived(message); +} + +void MetroViewerProcessHost::NotifyChannelConnected() { + if (channel_connected_event_) + channel_connected_event_->Signal(); +} + +} // namespace win8 diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h new file mode 100644 index 0000000..b9c3e77 --- /dev/null +++ b/win8/viewer/metro_viewer_process_host.h @@ -0,0 +1,94 @@ +// Copyright (c) 2013 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_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ +#define WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "base/threading/non_thread_safe.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_listener.h" +#include "ipc/ipc_sender.h" +#include "ui/gfx/native_widget_types.h" + +namespace base { +class SingleThreadTaskRunner; +class WaitableEvent; +} + +namespace IPC { +class Message; +} + +namespace win8 { + +// Abstract base class for various Metro viewer process host implementations. +class MetroViewerProcessHost : public IPC::Listener, + public IPC::Sender, + public base::NonThreadSafe { + public: + // Initializes a viewer process host over |ipc_channel_name|. The given task + // runner correspond to a thread on which IPC::Channel is created and used + // (e.g. IO thread). Instantly connects to the viewer process if one is + // already connected to |ipc_channel_name|; a viewer can otherwise be + // launched synchronously via LaunchViewerAndWaitForConnection(). + MetroViewerProcessHost(const std::string& ipc_channel_name, + base::SingleThreadTaskRunner* ipc_task_runner); + virtual ~MetroViewerProcessHost(); + + // Returns the process id of the viewer process if one is connected to this + // host, returns base::kNullProcessId otherwise. + base::ProcessId GetViewerProcessId(); + + // Launches the viewer process associated with the given |app_user_model_id| + // and blocks until that viewer process connects or until a timeout is + // reached. Returns true if the viewer process connects before the timeout is + // reached. NOTE: this assumes that the app referred to by |app_user_model_id| + // is registered as the default browser. + bool LaunchViewerAndWaitForConnection( + const base::string16& app_user_model_id); + + private: + // IPC::Sender implementation: + virtual bool Send(IPC::Message* msg) OVERRIDE; + + // IPC::Listener implementation: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void OnChannelError() OVERRIDE = 0; + + // Called over IPC by the viewer process to tell this host that it should be + // drawing to |target_surface|. + virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) = 0; + + void NotifyChannelConnected(); + + // Inner message filter used to handle connection event on the IPC channel + // proxy's background thread. This prevents consumers of + // MetroViewerProcessHost from having to pump messages on their own message + // loop. + class InternalMessageFilter : public IPC::ChannelProxy::MessageFilter { + public: + InternalMessageFilter(MetroViewerProcessHost* owner); + + // IPC::ChannelProxy::MessageFilter implementation. + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + + private: + MetroViewerProcessHost* owner_; + DISALLOW_COPY_AND_ASSIGN(InternalMessageFilter); + }; + + scoped_ptr<IPC::ChannelProxy> channel_; + scoped_ptr<base::WaitableEvent> channel_connected_event_; + + DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost); +}; + +} // namespace win8 + +#endif // WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ diff --git a/win8/win8.gyp b/win8/win8.gyp index 7b198a1..6e3d5a8 100644 --- a/win8/win8.gyp +++ b/win8/win8.gyp @@ -51,6 +51,20 @@ ], }, { + 'target_name': 'metro_viewer', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + '../ipc/ipc.gyp:ipc', + '../ui/aura/aura.gyp:aura', + '../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', + ], + 'sources': [ + 'viewer/metro_viewer_process_host.cc', + 'viewer/metro_viewer_process_host.h', + ], + }, + { 'target_name': 'test_support_win8', 'type': 'static_library', 'dependencies': [ |