diff options
author | Ben Murdoch <benm@google.com> | 2014-03-31 11:51:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-03-31 11:51:25 +0100 |
commit | effb81e5f8246d0db0270817048dc992db66e9fb (patch) | |
tree | cc45ced7dfde038c8f3d022ee1eeac207a68761e /win8 | |
parent | 4d26337013537c1acafbcb63b9b2b7e404c3adc9 (diff) | |
download | chromium_org-effb81e5f8246d0db0270817048dc992db66e9fb.tar.gz |
Merge from Chromium at DEPS revision 260458
This commit was generated by merge_to_master.py.
Change-Id: I140fa91b7f09c8efba4424e99ccb87b94a11d022
Diffstat (limited to 'win8')
-rw-r--r-- | win8/delegate_execute/command_execute_impl.cc | 2 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view_ash.cc | 42 | ||||
-rw-r--r-- | win8/metro_driver/direct3d_helper.cc | 47 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.cc | 66 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.gyp | 7 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver_win7.cc | 751 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 40 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 1 |
8 files changed, 794 insertions, 162 deletions
diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc index 405b24f0fc..4c37e7b952 100644 --- a/win8/delegate_execute/command_execute_impl.cc +++ b/win8/delegate_execute/command_execute_impl.cc @@ -432,7 +432,7 @@ EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() { base::FilePath chrome_exe; if (!FindChromeExe(&chrome_exe) || ShellUtil::GetChromeDefaultStateFromPath(chrome_exe) != - ShellUtil::DefaultState::IS_DEFAULT) { + ShellUtil::IS_DEFAULT) { AtlTrace("Chrome is not default: launching in desktop mode\n"); launch_mode = ECHUIM_DESKTOP; launch_mode_determined = true; diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc index dc5923c737..8e1f0e64d2 100644 --- a/win8/metro_driver/chrome_app_view_ash.cc +++ b/win8/metro_driver/chrome_app_view_ash.cc @@ -17,6 +17,7 @@ #include "base/threading/thread.h" #include "base/win/metro.h" #include "base/win/win_util.h" +#include "base/win/windows_version.h" #include "chrome/common/chrome_switches.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_proxy.h" @@ -272,8 +273,8 @@ bool WaitForChromeIPCConnection(const std::string& channel_name) { int ms_elapsed = 0; while (!IPC::Channel::IsNamedServerInitialized(channel_name) && ms_elapsed < 10000) { - ms_elapsed += 500; - Sleep(500); + ms_elapsed += 100; + Sleep(100); } return IPC::Channel::IsNamedServerInitialized(channel_name); } @@ -573,7 +574,7 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { CheckHR(hr); mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; - hr = window_->get_Dispatcher(&dispatcher); + hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); CheckHR(hr, "Get Dispatcher failed."); mswr::ComPtr<winui::Core::ICoreAcceleratorKeys> accelerator_keys; @@ -602,21 +603,23 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { &window_activated_token_); CheckHR(hr); - // Register for edge gesture notifications. - mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Input_EdgeGesture, - edge_gesture_statics.GetAddressOf()); - CheckHR(hr); - - mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture; - hr = edge_gesture_statics->GetForCurrentView(&edge_gesture); - CheckHR(hr); - - hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>( - this, &ChromeAppViewAsh::OnEdgeGestureCompleted).Get(), - &edgeevent_token_); - CheckHR(hr); + if (base::win::GetVersion() >= base::win::VERSION_WIN8) { + // Register for edge gesture notifications only for Windows 8 and above. + mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics; + hr = winrt_utils::CreateActivationFactory( + RuntimeClass_Windows_UI_Input_EdgeGesture, + edge_gesture_statics.GetAddressOf()); + CheckHR(hr); + + mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture; + hr = edge_gesture_statics->GetForCurrentView(&edge_gesture); + CheckHR(hr); + + hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>( + this, &ChromeAppViewAsh::OnEdgeGestureCompleted).Get(), + &edgeevent_token_); + CheckHR(hr); + } // By initializing the direct 3D swap chain with the corewindow // we can now directly blit to it from the browser process. @@ -627,6 +630,7 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { IFACEMETHODIMP ChromeAppViewAsh::Load(HSTRING entryPoint) { + // On Win7 |entryPoint| is NULL. DVLOG(1) << __FUNCTION__; return S_OK; } @@ -635,7 +639,7 @@ IFACEMETHODIMP ChromeAppViewAsh::Run() { DVLOG(1) << __FUNCTION__; mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; - HRESULT hr = window_->get_Dispatcher(&dispatcher); + HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); CheckHR(hr, "Dispatcher failed."); hr = window_->Activate(); diff --git a/win8/metro_driver/direct3d_helper.cc b/win8/metro_driver/direct3d_helper.cc index 056e84b4cb..d0c30cf712 100644 --- a/win8/metro_driver/direct3d_helper.cc +++ b/win8/metro_driver/direct3d_helper.cc @@ -7,7 +7,10 @@ #include "win8/metro_driver/winrt_utils.h" #include "base/logging.h" +#include "base/win/windows_version.h" +#include <corewindow.h> +#include <windows.applicationmodel.core.h> #include <windows.graphics.display.h> namespace { @@ -83,9 +86,15 @@ void Direct3DHelper::CreateDeviceResources() { } void Direct3DHelper::CreateWindowSizeDependentResources() { - CheckIfFailed(window_->get_Bounds(&window_bounds_)); - float window_width = ConvertDipsToPixels(window_bounds_.Width); - float window_height = ConvertDipsToPixels(window_bounds_.Height); + float window_width = 0; + float window_height = 0; + + if (base::win::GetVersion() >= base::win::VERSION_WIN8) { + // Windows 8 returns in DIPs. + CheckIfFailed(window_->get_Bounds(&window_bounds_)); + window_width = ConvertDipsToPixels(window_width); + window_height = ConvertDipsToPixels(window_height); + } // TODO(scottmg): Orientation. @@ -116,12 +125,32 @@ void Direct3DHelper::CreateWindowSizeDependentResources() { 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_)); + if (base::win::GetVersion() >= base::win::VERSION_WIN8) { + // On Win8 we need the CoreWindow interface to create the Swapchain. + CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow( + d3d_device_.Get(), + reinterpret_cast<IUnknown*>(window_), + &swap_chain_desc, + nullptr, + &swap_chain_)); + } else { + // On Win7 we need the raw HWND to create the Swapchain. + mswr::ComPtr<ICoreWindowInterop> interop; + CheckIfFailed(window_->QueryInterface(interop.GetAddressOf())); + HWND window = NULL; + interop->get_WindowHandle(&window); + + swap_chain_desc.Scaling = DXGI_SCALING_STRETCH; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + CheckIfFailed(dxgi_factory->CreateSwapChainForHwnd( + d3d_device_.Get(), + window, + &swap_chain_desc, + nullptr, + nullptr, + &swap_chain_)); + } } } diff --git a/win8/metro_driver/metro_driver.cc b/win8/metro_driver/metro_driver.cc index eb87754c71..a60af6b240 100644 --- a/win8/metro_driver/metro_driver.cc +++ b/win8/metro_driver/metro_driver.cc @@ -13,11 +13,9 @@ #include "base/logging.h" #include "base/logging_win.h" #include "base/win/scoped_comptr.h" +#include "base/win/windows_version.h" #include "win8/metro_driver/winrt_utils.h" -// TODO(siggi): Move this to GYP. -#pragma comment(lib, "runtimeobject.lib") - namespace { LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) { @@ -37,6 +35,17 @@ LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) { return EXCEPTION_CONTINUE_SEARCH; } +void SetMetroReportingFlags() { +#if !defined(NDEBUG) + // Set the error reporting flags to always raise an exception, + // which is then processed by our vectored exception handling + // above to log the error message. + winfoundtn::Diagnostics::SetErrorReportingFlags( + winfoundtn::Diagnostics::UseSetErrorInfo | + winfoundtn::Diagnostics::ForceExceptions); +#endif +} + // TODO(robertshield): This GUID is hard-coded in a bunch of places that // don't allow explicit includes. Find a single place for it to live. // {7FE69228-633E-4f06-80C1-527FEA23E3A7} @@ -44,7 +53,7 @@ const GUID kChromeTraceProviderName = { 0x7fe69228, 0x633e, 0x4f06, { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; -} +} // namespace #if !defined(COMPONENT_BUILD) // Required for base initialization. @@ -54,53 +63,58 @@ const GUID kChromeTraceProviderName = { base::AtExitManager at_exit; #endif +mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows8() { + SetMetroReportingFlags(); + HRESULT hr = ::Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); + if (FAILED(hr)) + CHECK(false); + mswr::ComPtr<winapp::Core::ICoreApplication> core_app; + hr = winrt_utils::CreateActivationFactory( + RuntimeClass_Windows_ApplicationModel_Core_CoreApplication, + core_app.GetAddressOf()); + if (FAILED(hr)) + CHECK(false); + return core_app; +} + +mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7(); + extern "C" __declspec(dllexport) int InitMetro() { + // Metro mode or its emulation is not supported in Vista or XP. + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return 1; // Initialize the command line. CommandLine::Init(0, NULL); + // Initialize the logging system. logging::LoggingSettings settings; settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; logging::InitLogging(settings); - #if defined(NDEBUG) logging::SetMinLogLevel(logging::LOG_ERROR); #else logging::SetMinLogLevel(logging::LOG_VERBOSE); - // Set the error reporting flags to always raise an exception, - // which is then processed by our vectored exception handling - // above to log the error message. - winfoundtn::Diagnostics::SetErrorReportingFlags( - winfoundtn::Diagnostics::UseSetErrorInfo | - winfoundtn::Diagnostics::ForceExceptions); - - HANDLE registration = + HANDLE registration = ::AddVectoredExceptionHandler(TRUE, ErrorReportingHandler); #endif - // Enable trace control and transport through event tracing for Windows. logging::LogEventProvider::Initialize(kChromeTraceProviderName); - DVLOG(1) << "InitMetro"; - mswrw::RoInitializeWrapper ro_initializer(RO_INIT_MULTITHREADED); - CheckHR(ro_initializer, "RoInitialize failed"); - + // OS specific initialization. mswr::ComPtr<winapp::Core::ICoreApplication> core_app; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_Core_CoreApplication, - core_app.GetAddressOf()); - CheckHR(hr, "Failed to create app factory"); - if (FAILED(hr)) - return 1; + if (base::win::GetVersion() < base::win::VERSION_WIN8) + core_app = InitWindows7(); + else + core_app = InitWindows8(); auto view_factory = mswr::Make<ChromeAppViewFactory>(core_app.Get()); - hr = core_app->Run(view_factory.Get()); + HRESULT hr = core_app->Run(view_factory.Get()); DVLOG(1) << "exiting InitMetro, hr=" << hr; #if !defined(NDEBUG) ::RemoveVectoredExceptionHandler(registration); #endif - return hr; } diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index 42fd9c72d5..34fbcdd988 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -22,6 +22,12 @@ 'AdditionalDependencies': [ 'D2D1.lib', 'D3D11.lib', + 'runtimeobject.lib', + ], + 'DelayLoadDLLs': [ + 'API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL', + 'API-MS-WIN-CORE-WINRT-L1-1-0.DLL', + 'API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL', ], }, 'VCCLCompilerTool': { @@ -76,6 +82,7 @@ 'display_properties.h', 'metro_driver.cc', 'metro_driver.h', + 'metro_driver_win7.cc', 'stdafx.h', 'winrt_utils.cc', 'winrt_utils.h', diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc index 253e527b8c..2e5aba73fc 100644 --- a/win8/metro_driver/metro_driver_win7.cc +++ b/win8/metro_driver/metro_driver_win7.cc @@ -3,41 +3,11 @@ // found in the LICENSE file. #include "stdafx.h" +#include <corewindow.h> -EXTERN_C IMAGE_DOS_HEADER __ImageBase; +#include "base/logging.h" -struct Globals { - LPTHREAD_START_ROUTINE host_main; - void* host_context; - HWND core_window; - HWND host_window; - HANDLE host_thread; - DWORD main_thread_id; -} globals; - - -void ODS(const char* str, LONG_PTR val = 0) { - char buf[80]; - size_t len = strlen(str); - if (len > 50) { - ::OutputDebugStringA("ODS: buffer too long"); - return; - } - - if (str[0] == '!') { - // Fatal error. - DWORD gle = ::GetLastError(); - if (::IsDebuggerPresent()) - __debugbreak(); - wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle); - ::MessageBoxA(NULL, buf, "!!!", MB_OK); - ::ExitProcess(gle); - } else { - // Just information. - wsprintfA(buf, "ODS:%s (%p)\n", str, val); - ::OutputDebugStringA(buf); - } -} +EXTERN_C IMAGE_DOS_HEADER __ImageBase; LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { @@ -45,15 +15,18 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, HDC hdc; switch (message) { case WM_PAINT: - hdc = BeginPaint(hwnd, &ps); + hdc = ::BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); break; + case WM_LBUTTONUP: + // TODO(cpu): Remove this test code. + ::InvalidateRect(hwnd, NULL, TRUE); + break; case WM_DESTROY: PostQuitMessage(0); - ODS("Metro WM_DESTROY received"); break; default: - return DefWindowProc(hwnd, message, wparam, lparam); + return ::DefWindowProc(hwnd, message, wparam, lparam); } return 0; } @@ -62,78 +35,660 @@ HWND CreateMetroTopLevelWindow() { HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase); WNDCLASSEXW wcex; wcex.cbSize = sizeof(wcex); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInst; - wcex.hIcon = 0; - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1); - wcex.lpszMenuName = 0; - wcex.lpszClassName = L"Windows.UI.Core.CoreWindow"; - wcex.hIconSm = 0; + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInst; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1); + wcex.lpszMenuName = 0; + wcex.lpszClassName = L"Windows.UI.Core.CoreWindow"; + wcex.hIconSm = 0; HWND hwnd = ::CreateWindowExW(0, MAKEINTATOM(::RegisterClassExW(&wcex)), - L"metro_metro", - WS_POPUP, - 0, 0, 0, 0, + L"metro_win7", + WS_POPUP | WS_VISIBLE, + 0, 0, 1024, 1024, NULL, NULL, hInst, NULL); return hwnd; } -DWORD WINAPI HostThread(void*) { - // The sleeps simulates the delay we have in the actual metro code - // which takes in account the corewindow being created and some other - // unknown machinations of metro. - ODS("Chrome main thread", ::GetCurrentThreadId()); - ::Sleep(30); - return globals.host_main(globals.host_context); -} +typedef winfoundtn::ITypedEventHandler< + winapp::Core::CoreApplicationView*, + winapp::Activation::IActivatedEventArgs*> ActivatedHandler; -extern "C" __declspec(dllexport) -int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { - ODS("InitMetro [Win7 emulation]"); - HWND window = CreateMetroTopLevelWindow(); - if (!window) - return 1; - // This magic incatation tells windows that the window is going fullscreen - // so the taskbar gets out of the wait automatically. - ::SetWindowPos(window, - HWND_TOP, - 0,0, - GetSystemMetrics(SM_CXSCREEN), - GetSystemMetrics(SM_CYSCREEN), - SWP_SHOWWINDOW); - - // Ready to start our caller. - globals.core_window = window; - globals.host_main = thread_proc; - globals.host_context = context; - HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL); - - // Main message loop. - MSG msg = {0}; - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - return (int) msg.wParam; -} +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler; -extern "C" _declspec(dllexport) HWND GetRootWindow() { - ODS("GetRootWindow", ULONG_PTR(globals.core_window)); - return globals.core_window; -} +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::AutomationProviderRequestedEventArgs*> + AutomationProviderHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::CharacterReceivedEventArgs*> CharEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::CoreWindowEventArgs*> CoreWindowEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::InputEnabledEventArgs*> InputEnabledEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::KeyEventArgs*> KeyEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::PointerEventArgs*> PointerEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::TouchHitTestingEventArgs*> TouchHitTestHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreDispatcher*, + winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler; + +// The following classes are the emulation of the WinRT system as exposed +// to metro applications. There is one application (ICoreApplication) which +// contains a series of Views (ICoreApplicationView) each one of them +// containing a CoreWindow which represents a surface that can drawn to +// and that receives events. +// +// Here is the general dependency hierachy in terms of interfaces: +// +// IFrameworkViewSource --> IFrameworkView +// ^ | +// | | metro app +// --------------------------------------------------------------------- +// | | winRT system +// | v +// ICoreApplication ICoreApplicationView +// | +// v +// ICoreWindow -----> ICoreWindowInterop +// | | +// | | +// v V +// ICoreDispatcher <==> real HWND +// +class CoreDispacherEmulation : + public mswr::RuntimeClass< + winui::Core::ICoreDispatcher, + winui::Core::ICoreAcceleratorKeys> { + public: + // ICoreDispatcher implementation: + virtual HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE ProcessEvents( + winui::Core::CoreProcessEventsOption options) { + // We don't support the other message pump modes. So we basically enter a + // traditional message loop that we only exit a teardown. + if (options != winui::Core::CoreProcessEventsOption_ProcessUntilQuit) + return E_FAIL; + + MSG msg = {0}; + while(::GetMessage(&msg, NULL, 0, 0) != 0) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + // TODO(cpu): figure what to do with msg.WParam which we would normally + // return here. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE RunAsync( + winui::Core::CoreDispatcherPriority priority, + winui::Core::IDispatchedHandler *agileCallback, + ABI::Windows::Foundation::IAsyncAction** asyncAction) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE RunIdleAsync( + winui::Core::IIdleDispatchedHandler *agileCallback, + winfoundtn::IAsyncAction** asyncAction) { + return S_OK; + } + + // ICoreAcceleratorKeys implementation: + virtual HRESULT STDMETHODCALLTYPE add_AcceleratorKeyActivated( + AcceleratorKeyEventHandler* handler, + EventRegistrationToken *pCookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_AcceleratorKeyActivated( + EventRegistrationToken cookie) { + return S_OK; + } + +}; + +class CoreWindowEmulation + : public mswr::RuntimeClass< + mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>, + winui::Core::ICoreWindow, ICoreWindowInterop> { + public: + CoreWindowEmulation() : core_hwnd_(NULL) { + dispatcher_ = mswr::Make<CoreDispacherEmulation>(); + core_hwnd_ = CreateMetroTopLevelWindow(); + } + + ~CoreWindowEmulation() { + ::DestroyWindow(core_hwnd_); + } + + // ICoreWindow implementation: + virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider( + IInspectable** value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_Bounds( + winfoundtn::Rect* value) { + RECT rect; + if (!::GetClientRect(core_hwnd_, &rect)) + return E_FAIL; + value->Width = rect.right; + value->Height = rect.bottom; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_CustomProperties( + winfoundtn::Collections::IPropertySet** value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_Dispatcher( + winui::Core::ICoreDispatcher** value) { + return dispatcher_.CopyTo(value); + } + + virtual HRESULT STDMETHODCALLTYPE get_FlowDirection( + winui::Core::CoreWindowFlowDirection* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE put_FlowDirection( + winui::Core::CoreWindowFlowDirection value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_IsInputEnabled( + boolean* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE put_IsInputEnabled( + boolean value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_PointerCursor( + winui::Core::ICoreCursor** value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE put_PointerCursor( + winui::Core::ICoreCursor* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_PointerPosition( + winfoundtn::Point* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_Visible( + boolean* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE Activate(void) { + // After we fire OnActivate on the View, Chrome calls us back here. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE Close(void) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetAsyncKeyState( + ABI::Windows::System::VirtualKey virtualKey, + winui::Core::CoreVirtualKeyStates* KeyState) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetKeyState( + ABI::Windows::System::VirtualKey virtualKey, + winui::Core::CoreVirtualKeyStates* KeyState) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetPointerCapture(void) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_Activated( + WindowActivatedHandler* handler, + EventRegistrationToken* pCookie) { + // TODO(cpu) implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Activated( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested( + AutomationProviderHandler* handler, + EventRegistrationToken* cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_CharacterReceived( + CharEventHandler* handler, + EventRegistrationToken* pCookie) { + // TODO(cpu) : implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_CharacterReceived( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_Closed( + CoreWindowEventHandler* handler, + EventRegistrationToken* pCookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Closed( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_InputEnabled( + InputEnabledEventHandler* handler, + EventRegistrationToken* pCookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_InputEnabled( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_KeyDown( + KeyEventHandler* handler, + EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_KeyDown( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_KeyUp( + KeyEventHandler* handler, + EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_KeyUp( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerCaptureLost( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerEntered( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerEntered( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerExited( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerExited( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerMoved( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + // TODO(cpu) : implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerMoved( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerPressed( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerPressed( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerReleased( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerReleased( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_TouchHitTesting( + TouchHitTestHandler* handler, + EventRegistrationToken* pCookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_TouchHitTesting( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_PointerWheelChanged( + PointerEventHandler* handler, + EventRegistrationToken* cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_SizeChanged( + SizeChangedHandler* handler, + EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_SizeChanged( + EventRegistrationToken cookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( + VisibilityChangedHandler* handler, + EventRegistrationToken* pCookie) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( + EventRegistrationToken cookie) { + return S_OK; + } + + // ICoreWindowInterop implementation: + virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) { + if (!core_hwnd_) + return E_FAIL; + *hwnd = core_hwnd_; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE put_MessageHandled( + boolean value) { + return S_OK; + } + + private: + HWND core_hwnd_; + mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher_; +}; + +class ActivatedEvent + : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> { + public: + ActivatedEvent(winapp::Activation::ActivationKind activation_kind) + : activation_kind_(activation_kind) { + } + + virtual HRESULT STDMETHODCALLTYPE get_Kind( + winapp::Activation::ActivationKind *value) { + *value = activation_kind_; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_PreviousExecutionState( + winapp::Activation::ApplicationExecutionState *value) { + *value = winapp::Activation::ApplicationExecutionState_ClosedByUser; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_SplashScreen( + winapp::Activation::ISplashScreen **value) { + return E_FAIL; + } + + private: + winapp::Activation::ActivationKind activation_kind_; +}; + +class CoreApplicationViewEmulation + : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> { + public: + CoreApplicationViewEmulation() { + core_window_ = mswr::Make<CoreWindowEmulation>(); + } + + HRESULT Activate() { + if (activated_handler_) { + auto ae = mswr::Make<ActivatedEvent>( + winapp::Activation::ActivationKind_File); + return activated_handler_->Invoke(this, ae.Get()); + } else { + return S_OK; + } + } + + // ICoreApplicationView implementation: + virtual HRESULT STDMETHODCALLTYPE get_CoreWindow( + winui::Core::ICoreWindow** value) { + if (!core_window_) + return E_FAIL; + return core_window_.CopyTo(value); + } + + virtual HRESULT STDMETHODCALLTYPE add_Activated( + ActivatedHandler* handler, + EventRegistrationToken* token) { + // The real component supports multiple handles but we don't yet. + if (activated_handler_) + return E_FAIL; + activated_handler_ = handler; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Activated( + EventRegistrationToken token) { + // Chrome never unregisters handlers, so we don't care about it. + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_IsMain( + boolean* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_IsHosted( + boolean* value) { + return S_OK; + } + + private: + mswr::ComPtr<winui::Core::ICoreWindow> core_window_; + mswr::ComPtr<ActivatedHandler> activated_handler_; +}; + +class CoreApplicationWin7Emulation + : public mswr::RuntimeClass<winapp::Core::ICoreApplication, + winapp::Core::ICoreApplicationExit> { + public: + // ICoreApplication implementation: + + virtual HRESULT STDMETHODCALLTYPE get_Id( + HSTRING* value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_Suspending( + winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler, + EventRegistrationToken* token) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Suspending( + EventRegistrationToken token) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_Resuming( + winfoundtn::IEventHandler<IInspectable*>* handler, + EventRegistrationToken* token) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Resuming( + EventRegistrationToken token) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE get_Properties( + winfoundtn::Collections::IPropertySet** value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetCurrentView( + winapp::Core::ICoreApplicationView** value) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE Run( + winapp::Core::IFrameworkViewSource* viewSource) { + HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf()); + if (FAILED(hr)) + return hr; + view_emulation_ = mswr::Make<CoreApplicationViewEmulation>(); + hr = app_view_->Initialize(view_emulation_.Get()); + if (FAILED(hr)) + return hr; + mswr::ComPtr<winui::Core::ICoreWindow> core_window; + hr = view_emulation_->get_CoreWindow(core_window.GetAddressOf()); + if (FAILED(hr)) + return hr; + hr = app_view_->SetWindow(core_window.Get()); + if (FAILED(hr)) + return hr; + hr = app_view_->Load(NULL); + if (FAILED(hr)) + return hr; + hr = view_emulation_->Activate(); + if (FAILED(hr)) + return hr; + return app_view_->Run(); + } + + virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories( + winfoundtn::IGetActivationFactory* activationFactoryCallback) { + return S_OK; + } + + // ICoreApplicationExit implementation: + + virtual HRESULT STDMETHODCALLTYPE Exit(void) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE add_Exiting( + winfoundtn::IEventHandler<IInspectable*>* handler, + EventRegistrationToken* token) { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE remove_Exiting( + EventRegistrationToken token) { + return S_OK; + } + + private: + mswr::ComPtr<winapp::Core::IFrameworkView> app_view_; + mswr::ComPtr<CoreApplicationViewEmulation> view_emulation_; +}; -extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) { - ODS("SetFrameWindow", ULONG_PTR(window)); - globals.host_window = window; -} -extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() { - return L""; +mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7() { + HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (FAILED(hr)) + CHECK(false); + return mswr::Make<CoreApplicationWin7Emulation>(); } diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc index 4fa519405c..a44ea3c473 100644 --- a/win8/viewer/metro_viewer_process_host.cc +++ b/win8/viewer/metro_viewer_process_host.cc @@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/process/process.h" +#include "base/process/process_handle.h" #include "base/strings/string16.h" #include "base/synchronization/waitable_event.h" #include "base/time/time.h" @@ -21,6 +22,12 @@ #include "ui/metro_viewer/metro_viewer_messages.h" #include "win8/viewer/metro_viewer_constants.h" +namespace { + +const int kViewerProcessConnectionTimeoutSecs = 60; + +} // namespace + namespace win8 { MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter( @@ -43,6 +50,26 @@ MetroViewerProcessHost::MetroViewerProcessHost( } MetroViewerProcessHost::~MetroViewerProcessHost() { + if (!channel_) + return; + + base::ProcessId viewer_process_id = GetViewerProcessId(); + channel_->Close(); + if (message_filter_) { + // Wait for the viewer process to go away. + if (viewer_process_id != base::kNullProcessId) { + base::ProcessHandle viewer_process = NULL; + base::OpenProcessHandleWithAccess( + viewer_process_id, + PROCESS_QUERY_INFORMATION | SYNCHRONIZE, + &viewer_process); + if (viewer_process) { + ::WaitForSingleObject(viewer_process, INFINITE); + ::CloseHandle(viewer_process); + } + } + channel_->RemoveFilter(message_filter_); + } } base::ProcessId MetroViewerProcessHost::GetViewerProcessId() { @@ -57,9 +84,8 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection( channel_connected_event_.reset(new base::WaitableEvent(false, false)); - scoped_refptr<InternalMessageFilter> message_filter( - new InternalMessageFilter(this)); - channel_->AddFilter(message_filter); + message_filter_ = new InternalMessageFilter(this); + channel_->AddFilter(message_filter_); base::win::ScopedComPtr<IApplicationActivationManager> activator; HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); @@ -75,13 +101,9 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection( // 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_->TimedWait(base::TimeDelta::FromSeconds( + kViewerProcessConnectionTimeoutSecs)); 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; } diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h index e156226e86..209a94cf72 100644 --- a/win8/viewer/metro_viewer_process_host.h +++ b/win8/viewer/metro_viewer_process_host.h @@ -96,6 +96,7 @@ class MetroViewerProcessHost : public IPC::Listener, scoped_ptr<IPC::ChannelProxy> channel_; scoped_ptr<base::WaitableEvent> channel_connected_event_; + scoped_refptr<InternalMessageFilter> message_filter_; DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost); }; |