diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
commit | 90dce4d38c5ff5333bea97d859d4e484e27edf0c (patch) | |
tree | 9c51c7dd97d24b15befa97a3482c51851e5383a1 /win8 | |
parent | 1515035f5917d10d363b0888a3615d581ad8b83f (diff) | |
download | chromium_org-90dce4d38c5ff5333bea97d859d4e484e27edf0c.tar.gz |
Merge from Chromium at DEPS revision r202854
This commit was generated by merge_to_master.py.
Change-Id: Idca323f71ef844a9e04f454d4f070b1e398f2deb
Diffstat (limited to 'win8')
-rw-r--r-- | win8/delegate_execute/command_execute_impl.cc | 24 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.gyp | 2 | ||||
-rw-r--r-- | win8/test/metro_registration_helper.cc | 79 | ||||
-rw-r--r-- | win8/test/metro_registration_helper.h | 20 | ||||
-rw-r--r-- | win8/test/ui_automation_client.cc | 6 | ||||
-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 |
8 files changed, 316 insertions, 31 deletions
diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc index 55a96bdf32..102f3e4f88 100644 --- a/win8/delegate_execute/command_execute_impl.cc +++ b/win8/delegate_execute/command_execute_impl.cc @@ -520,6 +520,30 @@ EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() { parameters_ = CommandLine(CommandLine::NO_PROGRAM); } +#if defined(USE_AURA) + if (launch_mode_determined) + return launch_mode; + + CComPtr<IExecuteCommandHost> host; + CComQIPtr<IServiceProvider> service_provider = m_spUnkSite; + if (service_provider) { + service_provider->QueryService(IID_IExecuteCommandHost, &host); + if (host) { + host->GetUIMode(&launch_mode); + } + } + + if (launch_mode >= ECHUIM_SYSTEM_LAUNCHER) { + // At the end if launch mode is not proper apply heuristics. + launch_mode = base::win::IsTouchEnabledDevice() ? + ECHUIM_IMMERSIVE : ECHUIM_DESKTOP; + } + + AtlTrace("Launching mode is %d\n", launch_mode); + launch_mode_determined = true; + return launch_mode; +#endif + base::win::RegKey reg_key; LONG key_result = reg_key.Create(HKEY_CURRENT_USER, chrome::kMetroRegistryPath, diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index f1f9892f51..623b000d2f 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/test/metro_registration_helper.cc b/win8/test/metro_registration_helper.cc index bfcfb29088..1d665dc2d6 100644 --- a/win8/test/metro_registration_helper.cc +++ b/win8/test/metro_registration_helper.cc @@ -4,6 +4,10 @@ #include "win8/test/metro_registration_helper.h" +#include <shlobj.h> + +#include <vector> + #include "base/command_line.h" #include "base/file_util.h" #include "base/files/file_path.h" @@ -11,7 +15,11 @@ #include "base/path_service.h" #include "base/process.h" #include "base/process_util.h" +#include "base/string16.h" +#include "base/win/scoped_co_mem.h" +#include "base/win/scoped_comptr.h" #include "base/win/scoped_handle.h" +#include "win8/test/open_with_dialog_controller.h" #include "win8/test/test_registrar_constants.h" namespace { @@ -22,12 +30,12 @@ const int kRegistrationTimeoutSeconds = 30; const wchar_t kChromeExe[] = L"chrome.exe"; const wchar_t kRegistrar[] = L"test_registrar.exe"; -} - -namespace win8 { - -bool RegisterTestDefaultBrowser(const string16& app_user_model_id, - const string16& viewer_process_name) { +// Registers chrome.exe as a potential Win8 default browser. It will then show +// up in the default browser selection dialog as kDefaultTestExeName. Intended +// to be used by a test binary in the build output directory and assumes the +// presence of test_registrar.exe, a viewer process, and all needed DLLs in the +// same directory as the calling module. +bool RegisterTestDefaultBrowser() { base::FilePath dir; if (!PathService::Get(base::DIR_EXE, &dir)) return false; @@ -40,15 +48,9 @@ bool RegisterTestDefaultBrowser(const string16& app_user_model_id, return false; } - // Perform the registration by invoking test_registrar.exe with the - // necessary flags: - // test_registrar.exe /RegServer --appid=<appid> --exe-name=<name> + // Perform the registration by invoking test_registrar.exe. CommandLine register_command(registrar); register_command.AppendArg("/RegServer"); - register_command.AppendSwitchNative(win8::test::kTestAppUserModelId, - app_user_model_id); - register_command.AppendSwitchNative(win8::test::kTestExeName, - viewer_process_name); base::win::ScopedHandle register_handle; if (base::LaunchProcess(register_command, base::LaunchOptions(), @@ -75,4 +77,55 @@ bool RegisterTestDefaultBrowser(const string16& app_user_model_id, return false; } +// Returns true if the test viewer's progid is the default handler for +// |protocol|. +bool IsTestDefaultForProtocol(const wchar_t* protocol) { + base::win::ScopedComPtr<IApplicationAssociationRegistration> registration; + HRESULT hr = registration.CreateInstance( + CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); + if (FAILED(hr)) { + LOG(ERROR) << std::hex << hr; + return false; + } + + base::win::ScopedCoMem<wchar_t> current_app; + hr = registration->QueryCurrentDefault(protocol, AT_URLPROTOCOL, + AL_EFFECTIVE, ¤t_app); + if (FAILED(hr)) { + LOG(ERROR) << std::hex << hr; + return false; + } + + return string16(win8::test::kDefaultTestProgId).compare(current_app) == 0; +} + +} // namespace + +namespace win8 { + +bool MakeTestDefaultBrowserSynchronously() { + static const wchar_t kDefaultBrowserProtocol[] = L"http"; + + if (!RegisterTestDefaultBrowser()) + return false; + + // Make sure the registration changes have been acknowledged by the shell + // before querying for the current default. + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, NULL, NULL); + + // OpenWithDialogController will fail if the Test Runner is already default + // since it will not show up verbatim in the dialog (e.g., in EN-US, it will + // be prefixed by "Keep using "). + if (IsTestDefaultForProtocol(kDefaultBrowserProtocol)) + return true; + + std::vector<base::string16> choices; + OpenWithDialogController controller; + HRESULT hr = controller.RunSynchronously( + NULL, kDefaultBrowserProtocol, win8::test::kDefaultTestExeName, &choices); + LOG_IF(ERROR, FAILED(hr)) << std::hex << hr; + DCHECK(IsTestDefaultForProtocol(kDefaultBrowserProtocol)); + return SUCCEEDED(hr); +} + } // namespace win8 diff --git a/win8/test/metro_registration_helper.h b/win8/test/metro_registration_helper.h index 86f00159f8..754c87b1e7 100644 --- a/win8/test/metro_registration_helper.h +++ b/win8/test/metro_registration_helper.h @@ -9,18 +9,14 @@ namespace win8 { -// Registers a viewer process as a potential Win8 default browser. Intended to -// be used by a test binary in the build output directory and assumes the -// presence of test_registrar.exe, a viewer process and all needed DLLs in the -// same directory as the calling module. The viewer process is then subsequently -// set as THE default Win8 browser, is activatable using the AppUserModelId in -// |app_user_model_id| and will show up in the default browser selection dialog -// as |viewer_process_name|. -// -// See also open_with_dialog_controller.h for a mechanism for setting THE -// default Win8 browser. -bool RegisterTestDefaultBrowser(const string16& app_user_model_id, - const string16& viewer_process_name); +// Synchronously makes chrome.exe THE default Win8 browser after which it is +// activatable into a Metro viewer process using +// win8::test::kDefaultTestAppUserModelId. Intended to be used by a test binary +// in the output directory and assumes the presence of test_registrar.exe, +// chrome.exe (the viewer process), and all needed DLLs in the same directory +// as the calling module. +// NOTE: COM must be initialized prior to calling this method. +bool MakeTestDefaultBrowserSynchronously(); } // namespace win8 diff --git a/win8/test/ui_automation_client.cc b/win8/test/ui_automation_client.cc index 8c8663083b..ef742f20fe 100644 --- a/win8/test/ui_automation_client.cc +++ b/win8/test/ui_automation_client.cc @@ -158,11 +158,7 @@ HRESULT UIAutomationClient::Context::EventHandler::HandleAutomationEvent( base::WeakPtr<UIAutomationClient::Context> UIAutomationClient::Context::Create() { Context* context = new Context(); - base::WeakPtr<Context> context_ptr(context->weak_ptr_factory_.GetWeakPtr()); - // Unbind from this thread so that the instance will bind to the automation - // thread when Initialize is called. - context->weak_ptr_factory_.DetachFromThread(); - return context_ptr; + return context->weak_ptr_factory_.GetWeakPtr(); } void UIAutomationClient::Context::DeleteOnAutomationThread() { diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc new file mode 100644 index 0000000000..f9450397f1 --- /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 0000000000..b9c3e77757 --- /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 7b198a18e1..6e3d5a8f76 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': [ |