diff options
author | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 16:55:32 +0000 |
---|---|---|
committer | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 16:55:32 +0000 |
commit | 5bbe1597629c0b99b1dd9a80a634bd575bbb2a93 (patch) | |
tree | f39459f508d22ed882d9a1b737e443ad2fd83411 /win8/viewer | |
parent | 9aa5c51b49de1934e40cd5e2b35b4d7187748e96 (diff) | |
download | chromium_src-5bbe1597629c0b99b1dd9a80a634bd575bbb2a93.zip chromium_src-5bbe1597629c0b99b1dd9a80a634bd575bbb2a93.tar.gz chromium_src-5bbe1597629c0b99b1dd9a80a634bd575bbb2a93.tar.bz2 |
Create MetroViewerProcessHost as a common base for TestMetroViewerProcessHost and ChromeMetroViewerProcessHost
Bringing LaunchViewerAndWaitForConnection() to the common base so that ChromeMetroViewerProcessHost can also benefit from it (required for ash browser tests).
BUG=179830
1st Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=201806
Reverted: https://src.chromium.org/viewvc/chrome?view=rev&revision=201966
R=robertshield@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/14629025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202113 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'win8/viewer')
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 108 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 94 |
2 files changed, 202 insertions, 0 deletions
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_ |