diff options
author | scottmg <scottmg@chromium.org> | 2016-01-18 17:40:29 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-19 01:41:47 +0000 |
commit | 5cc04f70e424020d8afe49bdc4c1c76683f0ea7b (patch) | |
tree | b2100e6c5456504d356d0050c84961c3972744a0 /win8 | |
parent | f4d0e6bbe12d1066bab7f8aa1bbd9e572dee6213 (diff) | |
download | chromium_src-5cc04f70e424020d8afe49bdc4c1c76683f0ea7b.zip chromium_src-5cc04f70e424020d8afe49bdc4c1c76683f0ea7b.tar.gz chromium_src-5cc04f70e424020d8afe49bdc4c1c76683f0ea7b.tar.bz2 |
Remove remote tree host and some related input and metro_driver code
Part of continued stripping out of Metro/Win8/Immersive mode.
BUG=558054
Review URL: https://codereview.chromium.org/1586843002
Cr-Commit-Position: refs/heads/master@{#370068}
Diffstat (limited to 'win8')
-rw-r--r-- | win8/BUILD.gn | 25 | ||||
-rw-r--r-- | win8/delegate_execute/BUILD.gn | 4 | ||||
-rw-r--r-- | win8/delegate_execute/command_execute_impl.cc | 15 | ||||
-rw-r--r-- | win8/delegate_execute/delegate_execute.gyp | 5 | ||||
-rw-r--r-- | win8/metro_driver/BUILD.gn | 10 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view_ash.cc | 1464 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view_ash.h | 262 | ||||
-rw-r--r-- | win8/metro_driver/file_picker.cc | 622 | ||||
-rw-r--r-- | win8/metro_driver/file_picker.h | 18 | ||||
-rw-r--r-- | win8/metro_driver/file_picker_ash.cc | 619 | ||||
-rw-r--r-- | win8/metro_driver/file_picker_ash.h | 157 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.cc | 135 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.gyp | 12 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.h | 17 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver_win7.cc | 1229 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_constants.cc | 13 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_constants.h | 20 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_exports.h | 29 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 346 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 221 | ||||
-rw-r--r-- | win8/win8.gyp | 29 |
21 files changed, 2 insertions, 5250 deletions
diff --git a/win8/BUILD.gn b/win8/BUILD.gn index fb43d2d..7b36f33 100644 --- a/win8/BUILD.gn +++ b/win8/BUILD.gn @@ -2,31 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("metro_viewer_constants") { - sources = [ - "viewer/metro_viewer_constants.cc", - "viewer/metro_viewer_constants.h", - ] -} - -component("metro_viewer") { - sources = [ - "viewer/metro_viewer_process_host.cc", - "viewer/metro_viewer_process_host.h", - ] - - defines = [ "METRO_VIEWER_IMPLEMENTATION" ] - - deps = [ - ":metro_viewer_constants", - "//base", - "//ipc", - "//ui/aura", - "//ui/gfx", - "//ui/metro_viewer", - ] -} - source_set("test_support_win8") { sources = [ "test/open_with_dialog_async.cc", diff --git a/win8/delegate_execute/BUILD.gn b/win8/delegate_execute/BUILD.gn index 8309dc6..4b7d911 100644 --- a/win8/delegate_execute/BUILD.gn +++ b/win8/delegate_execute/BUILD.gn @@ -50,10 +50,6 @@ source_set("lib") { "//ui/gfx/geometry", ] - if (use_aura) { - public_deps += [ "//win8:metro_viewer_constants" ] - } - if (is_chrome_branded) { public_deps += [ "//google_update" ] } diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc index 236f862..2711336 100644 --- a/win8/delegate_execute/command_execute_impl.cc +++ b/win8/delegate_execute/command_execute_impl.cc @@ -32,7 +32,6 @@ #include "ui/gfx/win/dpi.h" #include "win8/delegate_execute/chrome_util.h" #include "win8/delegate_execute/delegate_execute_util.h" -#include "win8/viewer/metro_viewer_constants.h" namespace { // Helper function to retrieve the url from IShellItem interface passed in. @@ -219,18 +218,8 @@ STDMETHODIMP CommandExecuteImpl::GetValue(enum AHE_TYPE* pahe) { return E_FAIL; } - EC_HOST_UI_MODE mode = GetLaunchMode(); - *pahe = (mode == ECHUIM_DESKTOP) ? AHE_DESKTOP : AHE_IMMERSIVE; - - // If we're going to return AHE_IMMERSIVE, then both the browser process and - // the metro viewer need to launch and connect before the user can start - // browsing. However we must not launch the metro viewer until we get a - // call to CommandExecuteImpl::Execute(). If we wait until then to launch - // the browser process as well, it will appear laggy while they connect to - // each other, so we pre-launch the browser process now. - if (*pahe == AHE_IMMERSIVE && verb_ != win8::kMetroViewerConnectVerb) { - LaunchChromeBrowserProcess(); - } + // TODO(scottmg): Can all go eventually https://crbug.com/558054. + *pahe = AHE_DESKTOP; return S_OK; } diff --git a/win8/delegate_execute/delegate_execute.gyp b/win8/delegate_execute/delegate_execute.gyp index 8dcd71f..b863dc5 100644 --- a/win8/delegate_execute/delegate_execute.gyp +++ b/win8/delegate_execute/delegate_execute.gyp @@ -73,11 +73,6 @@ }, }, 'conditions': [ - ['use_aura==1', { - 'dependencies': [ - '../win8.gyp:metro_viewer_constants', - ], - }], ['branding!="Chrome"', { 'dependencies!': [ '../../google_update/google_update.gyp:google_update', diff --git a/win8/metro_driver/BUILD.gn b/win8/metro_driver/BUILD.gn index 68c9a90..fc66690 100644 --- a/win8/metro_driver/BUILD.gn +++ b/win8/metro_driver/BUILD.gn @@ -10,9 +10,6 @@ shared_library("metro_driver") { sources = [ "display_properties.cc", "display_properties.h", - "metro_driver.cc", - "metro_driver.h", - "metro_driver_win7.cc", "stdafx.h", "winrt_utils.cc", "winrt_utils.h", @@ -36,17 +33,12 @@ shared_library("metro_driver") { if (use_aura) { sources += [ - "chrome_app_view_ash.cc", - "chrome_app_view_ash.h", "direct3d_helper.cc", "direct3d_helper.h", - "file_picker_ash.cc", - "file_picker_ash.h", ] deps += [ "//ui/events:gesture_detection", - "//win8:metro_viewer_constants", "//win8/metro_driver/ime", ] } else { @@ -57,8 +49,6 @@ shared_library("metro_driver") { "chrome_url_launch_handler.h", "devices_handler.cc", "devices_handler.h", - "file_picker.cc", - "file_picker.h", "metro_dialog_box.cc", "metro_dialog_box.h", "print_document_source.cc", diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc deleted file mode 100644 index 01f9ba2..0000000 --- a/win8/metro_driver/chrome_app_view_ash.cc +++ /dev/null @@ -1,1464 +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 "win8/metro_driver/stdafx.h" -#include "win8/metro_driver/chrome_app_view_ash.h" - -#include <corewindow.h> -#include <shellapi.h> -#include <stdint.h> -#include <windows.foundation.h> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/path_service.h" -#include "base/single_thread_task_runner.h" -#include "base/win/windows_version.h" -#include "chrome/common/chrome_switches.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_sender.h" -#include "ui/events/gesture_detection/motion_event.h" -#include "ui/events/win/system_event_state_lookup.h" -#include "ui/gfx/geometry/point_conversions.h" -#include "ui/gfx/win/dpi.h" -#include "ui/metro_viewer/metro_viewer_messages.h" -#include "win8/metro_driver/file_picker_ash.h" -#include "win8/metro_driver/ime/ime_popup_monitor.h" -#include "win8/metro_driver/ime/input_source.h" -#include "win8/metro_driver/ime/text_service.h" -#include "win8/metro_driver/metro_driver.h" -#include "win8/metro_driver/winrt_utils.h" -#include "win8/viewer/metro_viewer_constants.h" - -typedef winfoundtn::ITypedEventHandler< - winapp::Core::CoreApplicationView*, - winapp::Activation::IActivatedEventArgs*> ActivatedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::PointerEventArgs*> PointerEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::KeyEventArgs*> KeyEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreDispatcher*, - winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::CharacterReceivedEventArgs*> CharEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Input::EdgeGesture*, - winui::Input::EdgeGestureEventArgs*> EdgeEventHandler; - -// This function is exported by chrome.exe. -typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); - -// Global information used across the metro driver. -struct Globals { - winapp::Activation::ApplicationExecutionState previous_state; - winapp::Core::ICoreApplicationExit* app_exit; - BreakpadExceptionHandler breakpad_exception_handler; -} globals; - -extern float GetModernUIScale(); - -namespace { - -enum KeyModifier { - NONE, - SHIFT = 1, - CONTROL = 2, - ALT = 4 -}; - -const int kChromeChannelPollTimerMs = 100; - -// Helper function to send keystrokes via the SendInput function. -// mnemonic_char: The keystroke to be sent. -// modifiers: Combination with Alt, Ctrl, Shift, etc. -void SendKeySequence( - WORD mnemonic_char, KeyModifier modifiers) { - INPUT keys[4] = {}; // Keyboard events - int key_count = 0; // Number of generated events - - if (modifiers & SHIFT) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_SHIFT; - keys[key_count].ki.wScan = MapVirtualKey(VK_SHIFT, 0); - key_count++; - } - - if (modifiers & CONTROL) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_CONTROL; - keys[key_count].ki.wScan = MapVirtualKey(VK_CONTROL, 0); - key_count++; - } - - if (modifiers & ALT) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_MENU; - keys[key_count].ki.wScan = MapVirtualKey(VK_MENU, 0); - key_count++; - } - - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = mnemonic_char; - keys[key_count].ki.wScan = MapVirtualKey(mnemonic_char, 0); - key_count++; - - bool should_sleep = key_count > 1; - - // Send key downs. - for (int i = 0; i < key_count; i++) { - SendInput(1, &keys[ i ], sizeof(keys[0])); - keys[i].ki.dwFlags |= KEYEVENTF_KEYUP; - if (should_sleep) - Sleep(10); - } - - // Now send key ups in reverse order. - for (int i = key_count; i; i--) { - SendInput(1, &keys[ i - 1 ], sizeof(keys[0])); - if (should_sleep) - Sleep(10); - } -} - -class ChromeChannelListener : public IPC::Listener { - public: - ChromeChannelListener(base::MessageLoop* ui_loop, ChromeAppViewAsh* app_view) - : ui_task_runner_(ui_loop->task_runner()), app_view_(app_view) {} - - bool OnMessageReceived(const IPC::Message& message) override { - IPC_BEGIN_MESSAGE_MAP(ChromeChannelListener, message) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ActivateDesktop, - OnActivateDesktop) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MetroExit, OnMetroExit) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_OpenURLOnDesktop, - OnOpenURLOnDesktop) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursor, OnSetCursor) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileOpen, - OnDisplayFileOpenDialog) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileSaveAs, - OnDisplayFileSaveAsDialog) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplaySelectFolder, - OnDisplayFolderPicker) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursorPos, OnSetCursorPos) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeCancelComposition, - OnImeCancelComposition) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeTextInputClientUpdated, - OnImeTextInputClientChanged) - IPC_MESSAGE_UNHANDLED(__debugbreak()) - IPC_END_MESSAGE_MAP() - return true; - } - - void OnChannelError() override { - DVLOG(1) << "Channel error. Exiting."; - ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_), - TERMINATE_USING_KEY_SEQUENCE)); - - // In early Windows 8 versions the code above sometimes fails so we call - // it a second time with a NULL window which just calls Exit(). - ui_task_runner_->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_), - TERMINATE_USING_PROCESS_EXIT), - base::TimeDelta::FromMilliseconds(100)); - } - - private: - void OnActivateDesktop(const base::FilePath& shortcut, bool ash_exit) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnActivateDesktop, - base::Unretained(app_view_), shortcut, ash_exit)); - } - - void OnMetroExit() { - ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_), - TERMINATE_USING_KEY_SEQUENCE)); - } - - void OnOpenURLOnDesktop(const base::FilePath& shortcut, - const base::string16& url) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnOpenURLOnDesktop, - base::Unretained(app_view_), shortcut, url)); - } - - void OnSetCursor(int64_t cursor) { - ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnSetCursor, base::Unretained(app_view_), - reinterpret_cast<HCURSOR>(cursor))); - } - - void OnDisplayFileOpenDialog(const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path, - bool allow_multiple_files) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnDisplayFileOpenDialog, - base::Unretained(app_view_), title, filter, - default_path, allow_multiple_files)); - } - - void OnDisplayFileSaveAsDialog( - const MetroViewerHostMsg_SaveAsDialogParams& params) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnDisplayFileSaveAsDialog, - base::Unretained(app_view_), params)); - } - - void OnDisplayFolderPicker(const base::string16& title) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnDisplayFolderPicker, - base::Unretained(app_view_), title)); - } - - void OnSetCursorPos(int x, int y) { - VLOG(1) << "In IPC OnSetCursorPos: " << x << ", " << y; - ui_task_runner_->PostTask(FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnSetCursorPos, - base::Unretained(app_view_), x, y)); - } - - void OnImeCancelComposition() { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnImeCancelComposition, - base::Unretained(app_view_))); - } - - void OnImeTextInputClientChanged( - const std::vector<int32_t>& input_scopes, - const std::vector<metro_viewer::CharacterBounds>& character_bounds) { - ui_task_runner_->PostTask( - FROM_HERE, base::Bind(&ChromeAppViewAsh::OnImeUpdateTextInputClient, - base::Unretained(app_view_), input_scopes, - character_bounds)); - } - - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; - ChromeAppViewAsh* app_view_; -}; - -void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { - // We're entering a nested message loop, let's allow dispatching - // tasks while we're in there. - base::MessageLoop::current()->SetNestableTasksAllowed(true); - - // Enter main core message loop. There are several ways to exit it - // Nicely: - // 1 - User action like ALT-F4. - // 2 - Calling ICoreApplicationExit::Exit(). - // 3- Posting WM_CLOSE to the core window. - dispatcher->ProcessEvents( - winui::Core::CoreProcessEventsOption - ::CoreProcessEventsOption_ProcessUntilQuit); - - // Wind down the thread's chrome message loop. - base::MessageLoop::current()->QuitWhenIdle(); -} - -// Helper to return the state of the shift/control/alt keys. -uint32_t GetKeyboardEventFlags() { - uint32_t flags = 0; - if (ui::win::IsShiftPressed()) - flags |= ui::EF_SHIFT_DOWN; - if (ui::win::IsCtrlPressed()) - flags |= ui::EF_CONTROL_DOWN; - if (ui::win::IsAltPressed()) - flags |= ui::EF_ALT_DOWN; - return flags; -} - -bool LaunchChromeBrowserProcess(const wchar_t* additional_parameters, - winapp::Activation::IActivatedEventArgs* args) { - if (args) { - DVLOG(1) << __FUNCTION__ << ":" << ::GetCommandLineW(); - winapp::Activation::ActivationKind activation_kind; - CheckHR(args->get_Kind(&activation_kind)); - - DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind; - - if (activation_kind == winapp::Activation::ActivationKind_Launch) { - mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args; - if (args->QueryInterface( - winapp::Activation::IID_ILaunchActivatedEventArgs, - &launch_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Launch"; - mswrw::HString launch_args_str; - launch_args->get_Arguments(launch_args_str.GetAddressOf()); - base::string16 actual_launch_args( - MakeStdWString(launch_args_str.Get())); - if (actual_launch_args == win8::kMetroViewerConnectVerb) { - DVLOG(1) << __FUNCTION__ << "Not launching chrome server"; - return true; - } - } - } - } - - DVLOG(1) << "Launching chrome server"; - base::FilePath chrome_exe_path; - - if (!PathService::Get(base::FILE_EXE, &chrome_exe_path)) - return false; - - base::string16 parameters = L"--silent-launch --connect-to-metro-viewer "; - if (additional_parameters) - parameters += additional_parameters; - - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.nShow = SW_SHOWNORMAL; - sei.lpFile = chrome_exe_path.value().c_str(); - sei.lpDirectory = L""; - sei.lpParameters = parameters.c_str(); - ::ShellExecuteEx(&sei); - return true; -} - -} // namespace - -// This class helps decoding the pointer properties of an event. -class ChromeAppViewAsh::PointerInfoHandler { - public: - PointerInfoHandler(float metro_dpi_scale, float win32_dpi_scale) - : x_(0), - y_(0), - wheel_delta_(0), - pointer_id_(0), - update_kind_(winui::Input::PointerUpdateKind_Other), - timestamp_(0), - mouse_down_flags_(0), - is_horizontal_wheel_(0), - metro_dpi_scale_(metro_dpi_scale), - win32_dpi_scale_(win32_dpi_scale) {} - - HRESULT Init(winui::Core::IPointerEventArgs* args) { - HRESULT hr = args->get_CurrentPoint(&pointer_point_); - if (FAILED(hr)) - return hr; - - winfoundtn::Point point; - hr = pointer_point_->get_Position(&point); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<winui::Input::IPointerPointProperties> properties; - hr = pointer_point_->get_Properties(&properties); - if (FAILED(hr)) - return hr; - - hr = properties->get_PointerUpdateKind(&update_kind_); - if (FAILED(hr)) - return hr; - - hr = properties->get_MouseWheelDelta(&wheel_delta_); - if (FAILED(hr)) - return hr; - - is_horizontal_wheel_ = 0; - properties->get_IsHorizontalMouseWheel(&is_horizontal_wheel_); - - // The input coordinates are in DIP based on the metro scale factor. - // We want to convert it to DIP based on the win32 scale factor. - // We scale the point by the metro scale factor and then scale down - // via the win32 scale factor which achieves the needful. - gfx::Point dip_point_metro(point.X, point.Y); - gfx::Point scaled_point_metro = - gfx::ScaleToCeiledPoint(dip_point_metro, metro_dpi_scale_); - gfx::Point dip_point_win32 = - gfx::ScaleToCeiledPoint(scaled_point_metro, 1.0 / win32_dpi_scale_); - x_ = dip_point_win32.x(); - y_ = dip_point_win32.y(); - - pointer_point_->get_Timestamp(×tamp_); - pointer_point_->get_PointerId(&pointer_id_); - // Map the OS touch event id to a range allowed by the gesture recognizer. - if (IsTouch()) - pointer_id_ %= ui::MotionEvent::MAX_TOUCH_POINT_COUNT; - - boolean left_button_state; - hr = properties->get_IsLeftButtonPressed(&left_button_state); - if (FAILED(hr)) - return hr; - if (left_button_state) - mouse_down_flags_ |= ui::EF_LEFT_MOUSE_BUTTON; - - boolean right_button_state; - hr = properties->get_IsRightButtonPressed(&right_button_state); - if (FAILED(hr)) - return hr; - if (right_button_state) - mouse_down_flags_ |= ui::EF_RIGHT_MOUSE_BUTTON; - - boolean middle_button_state; - hr = properties->get_IsMiddleButtonPressed(&middle_button_state); - if (FAILED(hr)) - return hr; - if (middle_button_state) - mouse_down_flags_ |= ui::EF_MIDDLE_MOUSE_BUTTON; - - return S_OK; - } - - bool IsType(windevs::Input::PointerDeviceType type) const { - mswr::ComPtr<windevs::Input::IPointerDevice> pointer_device; - CheckHR(pointer_point_->get_PointerDevice(&pointer_device)); - windevs::Input::PointerDeviceType device_type; - CheckHR(pointer_device->get_PointerDeviceType(&device_type)); - return (device_type == type); - } - - bool IsMouse() const { - return IsType(windevs::Input::PointerDeviceType_Mouse); - } - - bool IsTouch() const { - return IsType(windevs::Input::PointerDeviceType_Touch); - } - - int32_t wheel_delta() const { return wheel_delta_; } - - // Identifies the button that changed. - ui::EventFlags changed_button() const { - switch (update_kind_) { - case winui::Input::PointerUpdateKind_LeftButtonPressed: - return ui::EF_LEFT_MOUSE_BUTTON; - case winui::Input::PointerUpdateKind_LeftButtonReleased: - return ui::EF_LEFT_MOUSE_BUTTON; - case winui::Input::PointerUpdateKind_RightButtonPressed: - return ui::EF_RIGHT_MOUSE_BUTTON; - case winui::Input::PointerUpdateKind_RightButtonReleased: - return ui::EF_RIGHT_MOUSE_BUTTON; - case winui::Input::PointerUpdateKind_MiddleButtonPressed: - return ui::EF_MIDDLE_MOUSE_BUTTON; - case winui::Input::PointerUpdateKind_MiddleButtonReleased: - return ui::EF_MIDDLE_MOUSE_BUTTON; - default: - return ui::EF_NONE; - } - } - - uint32_t mouse_down_flags() const { return mouse_down_flags_; } - - int x() const { return x_; } - int y() const { return y_; } - - uint32_t pointer_id() const { return pointer_id_; } - - uint64_t timestamp() const { return timestamp_; } - - winui::Input::PointerUpdateKind update_kind() const { return update_kind_; } - - bool is_horizontal_wheel() const { return !!is_horizontal_wheel_; } - - private: - int x_; - int y_; - int wheel_delta_; - uint32_t pointer_id_; - winui::Input::PointerUpdateKind update_kind_; - mswr::ComPtr<winui::Input::IPointerPoint> pointer_point_; - uint64_t timestamp_; - - // Bitmask of ui::EventFlags corresponding to the buttons that are currently - // down. - uint32_t mouse_down_flags_; - - // Set to true for a horizontal wheel message. - boolean is_horizontal_wheel_; - - // The metro device scale factor as reported by the winrt interfaces. - float metro_dpi_scale_; - // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to - // ui/gfx/win/dpi.cc for more information. - float win32_dpi_scale_; - - DISALLOW_COPY_AND_ASSIGN(PointerInfoHandler); -}; - -ChromeAppViewAsh::ChromeAppViewAsh() - : mouse_down_flags_(ui::EF_NONE), - ui_channel_(nullptr), - core_window_hwnd_(NULL), - metro_dpi_scale_(0), - win32_dpi_scale_(0), - last_cursor_(NULL), - channel_listener_(NULL) { - DVLOG(1) << __FUNCTION__; - globals.previous_state = - winapp::Activation::ApplicationExecutionState_NotRunning; -} - -ChromeAppViewAsh::~ChromeAppViewAsh() { - DVLOG(1) << __FUNCTION__; -} - -IFACEMETHODIMP -ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { - view_ = view; - DVLOG(1) << __FUNCTION__; - HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>( - this, &ChromeAppViewAsh::OnActivate).Get(), - &activated_token_); - CheckHR(hr); - return hr; -} - -IFACEMETHODIMP -ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { - window_ = window; - DVLOG(1) << __FUNCTION__; - - // Retrieve the native window handle via the interop layer. - mswr::ComPtr<ICoreWindowInterop> interop; - HRESULT hr = window->QueryInterface(interop.GetAddressOf()); - CheckHR(hr); - hr = interop->get_WindowHandle(&core_window_hwnd_); - CheckHR(hr); - - text_service_ = metro_driver::CreateTextService(this, core_window_hwnd_); - - hr = window_->add_SizeChanged(mswr::Callback<SizeChangedHandler>( - this, &ChromeAppViewAsh::OnSizeChanged).Get(), - &sizechange_token_); - CheckHR(hr); - - // Register for pointer and keyboard notifications. We forward - // them to the browser process via IPC. - hr = window_->add_PointerMoved(mswr::Callback<PointerEventHandler>( - this, &ChromeAppViewAsh::OnPointerMoved).Get(), - &pointermoved_token_); - CheckHR(hr); - - hr = window_->add_PointerPressed(mswr::Callback<PointerEventHandler>( - this, &ChromeAppViewAsh::OnPointerPressed).Get(), - &pointerpressed_token_); - CheckHR(hr); - - hr = window_->add_PointerReleased(mswr::Callback<PointerEventHandler>( - this, &ChromeAppViewAsh::OnPointerReleased).Get(), - &pointerreleased_token_); - CheckHR(hr); - - hr = window_->add_KeyDown(mswr::Callback<KeyEventHandler>( - this, &ChromeAppViewAsh::OnKeyDown).Get(), - &keydown_token_); - CheckHR(hr); - - hr = window_->add_KeyUp(mswr::Callback<KeyEventHandler>( - this, &ChromeAppViewAsh::OnKeyUp).Get(), - &keyup_token_); - CheckHR(hr); - - mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; - hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); - CheckHR(hr, "Get Dispatcher failed."); - - mswr::ComPtr<winui::Core::ICoreAcceleratorKeys> accelerator_keys; - hr = dispatcher.CopyTo(__uuidof(winui::Core::ICoreAcceleratorKeys), - reinterpret_cast<void**>( - accelerator_keys.GetAddressOf())); - CheckHR(hr, "QI for ICoreAcceleratorKeys failed."); - hr = accelerator_keys->add_AcceleratorKeyActivated( - mswr::Callback<AcceleratorKeyEventHandler>( - this, &ChromeAppViewAsh::OnAcceleratorKeyDown).Get(), - &accel_keydown_token_); - CheckHR(hr); - - hr = window_->add_PointerWheelChanged(mswr::Callback<PointerEventHandler>( - this, &ChromeAppViewAsh::OnWheel).Get(), - &wheel_token_); - CheckHR(hr); - - hr = window_->add_CharacterReceived(mswr::Callback<CharEventHandler>( - this, &ChromeAppViewAsh::OnCharacterReceived).Get(), - &character_received_token_); - CheckHR(hr); - - hr = window_->add_Activated(mswr::Callback<WindowActivatedHandler>( - this, &ChromeAppViewAsh::OnWindowActivated).Get(), - &window_activated_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. - direct3d_helper_.Initialize(window); - DVLOG(1) << "Initialized Direct3D."; - - // On Windows 8+ the WinRT interface IDisplayProperties which we use to get - // device scale factor does not return the correct values in metro mode. - // To workaround this we retrieve the device scale factor via the win32 way - // and scale input coordinates accordingly to pass them in DIP to chrome. - // TODO(ananta). Investigate and fix. - metro_dpi_scale_ = GetModernUIScale(); - win32_dpi_scale_ = gfx::GetDPIScale(); - DVLOG(1) << "Metro Scale is " << metro_dpi_scale_; - DVLOG(1) << "Win32 Scale is " << win32_dpi_scale_; - return S_OK; -} - -IFACEMETHODIMP -ChromeAppViewAsh::Load(HSTRING entryPoint) { - // On Win7 |entryPoint| is NULL. - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -IFACEMETHODIMP -ChromeAppViewAsh::Run() { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; - HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); - CheckHR(hr, "Dispatcher failed."); - - // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. - io_thread_.reset(new base::Thread("metro_IO_thread")); - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - io_thread_->StartWithOptions(options); - - ChromeChannelListener ui_channel_listener(&ui_loop_, this); - channel_listener_ = &ui_channel_listener; - - // We can't do anything until the Chrome browser IPC channel is initialized. - // Lazy initialization in a timer. - ui_loop_.PostDelayedTask(FROM_HERE, - base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode), - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs)); - - // Post the task that'll do the inner Metro message pumping to it. - ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); - ui_loop_.Run(); - - io_thread_.reset(NULL); - ui_channel_.reset(NULL); - channel_listener_ = NULL; - - DVLOG(0) << "ProcessEvents done, hr=" << hr; - return hr; -} - -IFACEMETHODIMP -ChromeAppViewAsh::Uninitialize() { - DVLOG(1) << __FUNCTION__; - metro_driver::RemoveImePopupObserver(this); - input_source_.reset(); - text_service_.reset(); - window_ = nullptr; - view_ = nullptr; - core_window_hwnd_ = NULL; - return S_OK; -} - -// static -HRESULT ChromeAppViewAsh::Unsnap() { - mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_ApplicationView, - view_statics.GetAddressOf()); - CheckHR(hr); - - winui::ViewManagement::ApplicationViewState state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - hr = view_statics->get_Value(&state); - CheckHR(hr); - - if (state == winui::ViewManagement::ApplicationViewState_Snapped) { - boolean success = FALSE; - hr = view_statics->TryUnsnap(&success); - - if (FAILED(hr) || !success) { - LOG(ERROR) << "Failed to unsnap. Error 0x" << hr; - if (SUCCEEDED(hr)) - hr = E_UNEXPECTED; - } - } - return hr; -} - -void ChromeAppViewAsh::OnActivateDesktop(const base::FilePath& file_path, - bool ash_exit) { - DVLOG(1) << "ChannelAppViewAsh::OnActivateDesktop\n"; - - if (ash_exit) { - // As we are the top level window, the exiting is done async so we manage - // to execute the entire function including the final Send(). - OnMetroExit(TERMINATE_USING_KEY_SEQUENCE); - } - - // We are just executing delegate_execute here without parameters. Assumption - // here is that this process will be reused by shell when asking for - // IExecuteCommand interface. - - // TODO(shrikant): Consolidate ShellExecuteEx with SEE_MASK_FLAG_LOG_USAGE - // and place it metro.h or similar accessible file from all code code paths - // using this function. - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_FLAG_LOG_USAGE; - sei.nShow = SW_SHOWNORMAL; - sei.lpFile = file_path.value().c_str(); - sei.lpParameters = NULL; - if (!ash_exit) - sei.fMask |= SEE_MASK_NOCLOSEPROCESS; - ::ShellExecuteExW(&sei); - if (!ash_exit) { - ::TerminateProcess(sei.hProcess, 0); - ::CloseHandle(sei.hProcess); - } -} - -void ChromeAppViewAsh::OnOpenURLOnDesktop(const base::FilePath& shortcut, - const base::string16& url) { - base::FilePath::StringType file = shortcut.value(); - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_FLAG_LOG_USAGE; - sei.nShow = SW_SHOWNORMAL; - sei.lpFile = file.c_str(); - sei.lpDirectory = L""; - sei.lpParameters = url.c_str(); - ShellExecuteEx(&sei); -} - -void ChromeAppViewAsh::OnSetCursor(HCURSOR cursor) { - ::SetCursor(cursor); - last_cursor_ = cursor; -} - -void ChromeAppViewAsh::OnDisplayFileOpenDialog( - const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path, - bool allow_multiple_files) { - DVLOG(1) << __FUNCTION__; - - // The OpenFilePickerSession instance is deleted when we receive a - // callback from the OpenFilePickerSession class about the completion of the - // operation. - FilePickerSessionBase* file_picker_ = - new OpenFilePickerSession(this, - title, - filter, - default_path, - allow_multiple_files); - file_picker_->Run(); -} - -void ChromeAppViewAsh::OnDisplayFileSaveAsDialog( - const MetroViewerHostMsg_SaveAsDialogParams& params) { - DVLOG(1) << __FUNCTION__; - - // The SaveFilePickerSession instance is deleted when we receive a - // callback from the SaveFilePickerSession class about the completion of the - // operation. - FilePickerSessionBase* file_picker_ = - new SaveFilePickerSession(this, params); - file_picker_->Run(); -} - -void ChromeAppViewAsh::OnDisplayFolderPicker(const base::string16& title) { - DVLOG(1) << __FUNCTION__; - // The FolderPickerSession instance is deleted when we receive a - // callback from the FolderPickerSession class about the completion of the - // operation. - FilePickerSessionBase* file_picker_ = new FolderPickerSession(this, title); - file_picker_->Run(); -} - -void ChromeAppViewAsh::OnSetCursorPos(int x, int y) { - if (ui_channel_) { - ::SetCursorPos(x, y); - DVLOG(1) << "In UI OnSetCursorPos: " << x << ", " << y; - ui_channel_->Send(new MetroViewerHostMsg_SetCursorPosAck()); - // Generate a fake mouse move which matches the SetCursor coordinates as - // the browser expects to receive a mouse move for these coordinates. - // It is not clear why we don't receive a real mouse move in response to - // the SetCursorPos calll above. - ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(x, y, 0)); - } -} - -void ChromeAppViewAsh::OnOpenFileCompleted( - OpenFilePickerSession* open_file_picker, - bool success) { - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "Success: " << success; - if (ui_channel_) { - if (open_file_picker->allow_multi_select()) { - ui_channel_->Send(new MetroViewerHostMsg_MultiFileOpenDone( - success, open_file_picker->filenames())); - } else { - ui_channel_->Send(new MetroViewerHostMsg_FileOpenDone( - success, base::FilePath(open_file_picker->result()))); - } - } - delete open_file_picker; -} - -void ChromeAppViewAsh::OnSaveFileCompleted( - SaveFilePickerSession* save_file_picker, - bool success) { - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "Success: " << success; - if (ui_channel_) { - ui_channel_->Send(new MetroViewerHostMsg_FileSaveAsDone( - success, - base::FilePath(save_file_picker->result()), - save_file_picker->filter_index())); - } - delete save_file_picker; -} - -void ChromeAppViewAsh::OnFolderPickerCompleted( - FolderPickerSession* folder_picker, - bool success) { - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "Success: " << success; - if (ui_channel_) { - ui_channel_->Send(new MetroViewerHostMsg_SelectFolderDone( - success, - base::FilePath(folder_picker->result()))); - } - delete folder_picker; -} - -void ChromeAppViewAsh::OnImeCancelComposition() { - if (!text_service_) - return; - text_service_->CancelComposition(); -} - -void ChromeAppViewAsh::OnImeUpdateTextInputClient( - const std::vector<int32_t>& input_scopes, - const std::vector<metro_viewer::CharacterBounds>& character_bounds) { - if (!text_service_) - return; - text_service_->OnDocumentChanged(input_scopes, character_bounds); -} - -void ChromeAppViewAsh::OnImePopupChanged(ImePopupObserver::EventType event) { - if (!ui_channel_) - return; - switch (event) { - case ImePopupObserver::kPopupShown: - ui_channel_->Send(new MetroViewerHostMsg_ImeCandidatePopupChanged(true)); - return; - case ImePopupObserver::kPopupHidden: - ui_channel_->Send(new MetroViewerHostMsg_ImeCandidatePopupChanged(false)); - return; - case ImePopupObserver::kPopupUpdated: - // TODO(kochi): Support this event for W3C IME API proposal. - // See crbug.com/238585. - return; - default: - NOTREACHED() << "unknown event type: " << event; - return; - } -} - -// Function to Exit metro chrome cleanly. If we are in the foreground -// then we try and exit by sending an Alt+F4 key combination to the core -// window which ensures that the chrome application tile does not show up in -// the running metro apps list on the top left corner. -void ChromeAppViewAsh::OnMetroExit(MetroTerminateMethod method) { - if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - HWND core_window = core_window_hwnd(); - if (method == TERMINATE_USING_KEY_SEQUENCE && core_window != NULL && - core_window == ::GetForegroundWindow()) { - DVLOG(1) << "We are in the foreground. Exiting via Alt F4"; - SendKeySequence(VK_F4, ALT); - if (ui_channel_) - ui_channel_->Close(); - } else { - globals.app_exit->Exit(); - } - } else { - if (ui_channel_) - ui_channel_->Close(); - - HWND core_window = core_window_hwnd(); - ::PostMessage(core_window, WM_CLOSE, 0, 0); - - globals.app_exit->Exit(); - } -} - -void ChromeAppViewAsh::OnInputSourceChanged() { - if (!input_source_) - return; - - DCHECK(ui_channel_); - - LANGID langid = 0; - bool is_ime = false; - if (!input_source_->GetActiveSource(&langid, &is_ime)) { - LOG(ERROR) << "GetActiveSource failed"; - return; - } - ui_channel_->Send(new MetroViewerHostMsg_ImeInputSourceChanged(langid, - is_ime)); -} - -void ChromeAppViewAsh::OnCompositionChanged( - const base::string16& text, - int32_t selection_start, - int32_t selection_end, - const std::vector<metro_viewer::UnderlineInfo>& underlines) { - ui_channel_->Send(new MetroViewerHostMsg_ImeCompositionChanged( - text, selection_start, selection_end, underlines)); -} - -void ChromeAppViewAsh::OnTextCommitted(const base::string16& text) { - ui_channel_->Send(new MetroViewerHostMsg_ImeTextCommitted(text)); -} - -void ChromeAppViewAsh::SendMouseButton(int x, - int y, - int extra, - ui::EventType event_type, - uint32_t flags, - ui::EventFlags changed_button, - bool is_horizontal_wheel) { - if (!ui_channel_) - return; - MetroViewerHostMsg_MouseButtonParams params; - params.x = static_cast<int32_t>(x); - params.y = static_cast<int32_t>(y); - params.extra = static_cast<int32_t>(extra); - params.event_type = event_type; - params.flags = static_cast<int32_t>(flags); - params.changed_button = changed_button; - params.is_horizontal_wheel = is_horizontal_wheel; - ui_channel_->Send(new MetroViewerHostMsg_MouseButton(params)); -} - -void ChromeAppViewAsh::GenerateMouseEventFromMoveIfNecessary( - const PointerInfoHandler& pointer) { - ui::EventType event_type; - // For aura we want the flags to include the button that was released, thus - // we or the old and new. - uint32_t mouse_down_flags = pointer.mouse_down_flags() | mouse_down_flags_; - mouse_down_flags_ = pointer.mouse_down_flags(); - switch (pointer.update_kind()) { - case winui::Input::PointerUpdateKind_LeftButtonPressed: - case winui::Input::PointerUpdateKind_RightButtonPressed: - case winui::Input::PointerUpdateKind_MiddleButtonPressed: - event_type = ui::ET_MOUSE_PRESSED; - break; - case winui::Input::PointerUpdateKind_LeftButtonReleased: - case winui::Input::PointerUpdateKind_RightButtonReleased: - case winui::Input::PointerUpdateKind_MiddleButtonReleased: - event_type = ui::ET_MOUSE_RELEASED; - break; - default: - return; - } - SendMouseButton(pointer.x(), pointer.y(), 0, event_type, - mouse_down_flags | GetKeyboardEventFlags(), - pointer.changed_button(), pointer.is_horizontal_wheel()); -} - -HRESULT ChromeAppViewAsh::OnActivate( - winapp::Core::ICoreApplicationView*, - winapp::Activation::IActivatedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - // Note: If doing more work in this function, you migth need to call - // get_PreviousExecutionState() and skip the work if the result is - // ApplicationExecutionState_Running and globals.previous_state is too. - args->get_PreviousExecutionState(&globals.previous_state); - DVLOG(1) << "Previous Execution State: " << globals.previous_state; - - winapp::Activation::ActivationKind activation_kind; - CheckHR(args->get_Kind(&activation_kind)); - DVLOG(1) << "Activation kind: " << activation_kind; - - if (activation_kind == winapp::Activation::ActivationKind_Search) - HandleSearchRequest(args); - else if (activation_kind == winapp::Activation::ActivationKind_Protocol) - HandleProtocolRequest(args); - else - LaunchChromeBrowserProcess(NULL, args); - // We call ICoreWindow::Activate after the handling for the search/protocol - // requests because Chrome can be launched to handle a search request which - // in turn launches the chrome browser process in desktop mode via - // ShellExecute. If we call ICoreWindow::Activate before this, then - // Windows kills the metro chrome process when it calls ShellExecute. Seems - // to be a bug. - window_->Activate(); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - if (!ui_channel_) - return S_OK; - - PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - - if (pointer.IsMouse()) { - // If the mouse was moved towards the charms or the OS specific section, - // the cursor may change from what the browser last set. Restore it here. - if (::GetCursor() != last_cursor_) - SetCursor(last_cursor_); - - GenerateMouseEventFromMoveIfNecessary(pointer); - ui_channel_->Send(new MetroViewerHostMsg_MouseMoved( - pointer.x(), - pointer.y(), - mouse_down_flags_ | GetKeyboardEventFlags())); - } else { - DCHECK(pointer.IsTouch()); - ui_channel_->Send(new MetroViewerHostMsg_TouchMoved(pointer.x(), - pointer.y(), - pointer.timestamp(), - pointer.pointer_id())); - } - return S_OK; -} - -// NOTE: From experimentation, it seems like Metro only sends a PointerPressed -// event for the first button pressed and the last button released in a sequence -// of mouse events. -// For example, a sequence of LEFT_DOWN, RIGHT_DOWN, LEFT_UP, RIGHT_UP results -// only in PointerPressed(LEFT)/PointerReleased(RIGHT) events. Intermediary -// presses and releases are tracked in OnPointMoved(). -HRESULT ChromeAppViewAsh::OnPointerPressed( - winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - if (!ui_channel_) - return S_OK; - - PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - - if (pointer.IsMouse()) { - mouse_down_flags_ = pointer.mouse_down_flags(); - SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_PRESSED, - mouse_down_flags_ | GetKeyboardEventFlags(), - pointer.changed_button(), pointer.is_horizontal_wheel()); - } else { - DCHECK(pointer.IsTouch()); - ui_channel_->Send(new MetroViewerHostMsg_TouchDown(pointer.x(), - pointer.y(), - pointer.timestamp(), - pointer.pointer_id())); - } - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnPointerReleased( - winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - if (!ui_channel_) - return S_OK; - - PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - - if (pointer.IsMouse()) { - mouse_down_flags_ = ui::EF_NONE; - SendMouseButton(pointer.x(), pointer.y(), 0, ui::ET_MOUSE_RELEASED, - static_cast<uint32_t>(pointer.changed_button()) | - GetKeyboardEventFlags(), - pointer.changed_button(), pointer.is_horizontal_wheel()); - } else { - DCHECK(pointer.IsTouch()); - ui_channel_->Send(new MetroViewerHostMsg_TouchUp(pointer.x(), - pointer.y(), - pointer.timestamp(), - pointer.pointer_id())); - } - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnWheel( - winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - if (!ui_channel_) - return S_OK; - - PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_); - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - DCHECK(pointer.IsMouse()); - SendMouseButton(pointer.x(), pointer.y(), pointer.wheel_delta(), - ui::ET_MOUSEWHEEL, GetKeyboardEventFlags(), ui::EF_NONE, - pointer.is_horizontal_wheel()); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnKeyDown( - winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args) { - if (!ui_channel_) - return S_OK; - - winsys::VirtualKey virtual_key; - HRESULT hr = args->get_VirtualKey(&virtual_key); - if (FAILED(hr)) - return hr; - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, - status.RepeatCount, - status.ScanCode, - GetKeyboardEventFlags())); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnKeyUp( - winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args) { - if (!ui_channel_) - return S_OK; - - winsys::VirtualKey virtual_key; - HRESULT hr = args->get_VirtualKey(&virtual_key); - if (FAILED(hr)) - return hr; - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, - status.RepeatCount, - status.ScanCode, - GetKeyboardEventFlags())); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown( - winui::Core::ICoreDispatcher* sender, - winui::Core::IAcceleratorKeyEventArgs* args) { - if (!ui_channel_) - return S_OK; - - winsys::VirtualKey virtual_key; - HRESULT hr = args->get_VirtualKey(&virtual_key); - if (FAILED(hr)) - return hr; - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - winui::Core::CoreAcceleratorKeyEventType event_type; - hr = args->get_EventType(&event_type); - if (FAILED(hr)) - return hr; - - uint32_t keyboard_flags = GetKeyboardEventFlags(); - - switch (event_type) { - case winui::Core::CoreAcceleratorKeyEventType_SystemCharacter: - ui_channel_->Send(new MetroViewerHostMsg_Character(virtual_key, - status.RepeatCount, - status.ScanCode, - keyboard_flags)); - break; - - case winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown: - // Don't send the Alt + F4 combination to Chrome as this is intended to - // shut the metro environment down. Reason we check for Control here is - // Windows does not shutdown metro if Ctrl is pressed along with Alt F4. - // Other key combinations with Alt F4 shutdown metro. - if ((virtual_key == VK_F4) && ((keyboard_flags & ui::EF_ALT_DOWN) && - !(keyboard_flags & ui::EF_CONTROL_DOWN))) - return S_OK; - // Don't send the EF_ALT_DOWN modifier along with the IPC message for - // the Alt or F10 key. The accelerator for VKEY_MENU is registered - // without modifiers in Chrome for historical reasons. Not sending the - // EF_ALT_DOWN modifier ensures that the accelerator is processed - // correctly. - if (virtual_key == winsys::VirtualKey_Menu) - keyboard_flags &= ~ui::EF_ALT_DOWN; - ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, - status.RepeatCount, - status.ScanCode, - keyboard_flags)); - break; - - case winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp: - ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, - status.RepeatCount, - status.ScanCode, - keyboard_flags)); - break; - - default: - break; - } - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnCharacterReceived( - winui::Core::ICoreWindow* sender, - winui::Core::ICharacterReceivedEventArgs* args) { - if (!ui_channel_) - return S_OK; - - unsigned int char_code = 0; - HRESULT hr = args->get_KeyCode(&char_code); - if (FAILED(hr)) - return hr; - - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - ui_channel_->Send(new MetroViewerHostMsg_Character(char_code, - status.RepeatCount, - status.ScanCode, - GetKeyboardEventFlags())); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnWindowActivated( - winui::Core::ICoreWindow* sender, - winui::Core::IWindowActivatedEventArgs* args) { - if (!ui_channel_) - return S_OK; - - if (args) { - winui::Core::CoreWindowActivationState state; - HRESULT hr = args->get_WindowActivationState(&state); - if (FAILED(hr)) - return hr; - - // Treat both full activation (Ash was reopened from the Start Screen or - // from any other Metro entry point in Windows) and pointer activation - // (user clicked back in Ash after using another app on another monitor) - // the same. - if (state == winui::Core::CoreWindowActivationState_CodeActivated || - state == winui::Core::CoreWindowActivationState_PointerActivated) { - ui_channel_->Send(new MetroViewerHostMsg_WindowActivated(false)); - } - } else { - // On Windows 7, we force a repaint when the window is activated. - ui_channel_->Send(new MetroViewerHostMsg_WindowActivated(true)); - } - if (text_service_) - text_service_->OnWindowActivated(); - return S_OK; -} - -HRESULT ChromeAppViewAsh::HandleSearchRequest( - winapp::Activation::IActivatedEventArgs* args) { - mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args; - CheckHR(args->QueryInterface( - winapp::Activation::IID_ISearchActivatedEventArgs, &search_args)); - - if (!ui_channel_) { - DVLOG(1) << "Launched to handle search request"; - LaunchChromeBrowserProcess(L"--windows8-search", args); - } - - mswrw::HString search_string; - CheckHR(search_args->get_QueryText(search_string.GetAddressOf())); - base::string16 search_text(MakeStdWString(search_string.Get())); - - ui_loop_.PostTask(FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnSearchRequest, - base::Unretained(this), - search_text)); - return S_OK; -} - -HRESULT ChromeAppViewAsh::HandleProtocolRequest( - winapp::Activation::IActivatedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - if (!ui_channel_) - DVLOG(1) << "Launched to handle url request"; - - mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs> - protocol_args; - CheckHR(args->QueryInterface( - winapp::Activation::IID_IProtocolActivatedEventArgs, - &protocol_args)); - - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - protocol_args->get_Uri(&uri); - mswrw::HString url; - uri->get_AbsoluteUri(url.GetAddressOf()); - base::string16 actual_url(MakeStdWString(url.Get())); - DVLOG(1) << "Received url request: " << actual_url; - - ui_loop_.PostTask(FROM_HERE, - base::Bind(&ChromeAppViewAsh::OnNavigateToUrl, - base::Unretained(this), - actual_url)); - return S_OK; -} - -HRESULT ChromeAppViewAsh::OnEdgeGestureCompleted( - winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args) { - if (ui_channel_) - ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture()); - return S_OK; -} - -void ChromeAppViewAsh::OnSearchRequest(const base::string16& search_string) { - if (ui_channel_) - ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string)); -} - -void ChromeAppViewAsh::OnNavigateToUrl(const base::string16& url) { - if (ui_channel_) - ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url)); -} - -HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args) { - if (!window_ || !ui_channel_) { - return S_OK; - } - - // winui::Core::IWindowSizeChangedEventArgs args->Size appears to return - // scaled values under HiDPI. We will instead use GetWindowRect() which - // should always return values in Pixels. - RECT rect = {0}; - ::GetWindowRect(core_window_hwnd_, &rect); - - uint32_t cx = static_cast<uint32_t>(rect.right - rect.left); - uint32_t cy = static_cast<uint32_t>(rect.bottom - rect.top); - - DVLOG(1) << "Window size changed: width=" << cx << ", height=" << cy; - ui_channel_->Send(new MetroViewerHostMsg_WindowSizeChanged(cx, cy)); - return S_OK; -} - -void ChromeAppViewAsh::StartChromeOSMode() { - static int ms_elapsed = 0; - - if (!IPC::Channel::IsNamedServerInitialized( - win8::kMetroViewerIPCChannelName) && ms_elapsed < 10000) { - ms_elapsed += 100; - ui_loop_.PostDelayedTask(FROM_HERE, - base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode), - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs)); - return; - } - - if (!IPC::Channel::IsNamedServerInitialized( - win8::kMetroViewerIPCChannelName)) { - DVLOG(1) << "Failed to connect to chrome channel : " - << win8::kMetroViewerIPCChannelName; - DVLOG(1) << "Exiting. Elapsed time :" << ms_elapsed; - PostMessage(core_window_hwnd_, WM_CLOSE, 0, 0); - return; - } - - DVLOG(1) << "Found channel : " << win8::kMetroViewerIPCChannelName; - - DCHECK(channel_listener_); - - // In Aura mode we create an IPC channel to the browser, then ask it to - // connect to us. - ui_channel_ = - IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName, - IPC::Channel::MODE_NAMED_CLIENT, - channel_listener_, - io_thread_->task_runner()); - DVLOG(1) << "Created channel proxy"; - - // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the - // browser will use D3D from the browser process to present to our Window. - ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( - gfx::NativeViewId(core_window_hwnd_), - win32_dpi_scale_)); - DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_; - - // Send an initial size message so that the Ash root window host gets sized - // correctly. - RECT rect = {0}; - ::GetWindowRect(core_window_hwnd_, &rect); - ui_channel_->Send( - new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left, - rect.bottom - rect.top)); - - input_source_ = metro_driver::InputSource::Create(); - if (input_source_) { - input_source_->AddObserver(this); - // Send an initial input source. - OnInputSourceChanged(); - } - - // Start receiving IME popup window notifications. - metro_driver::AddImePopupObserver(this); - - DVLOG(1) << "Channel setup complete"; -} - -/////////////////////////////////////////////////////////////////////////////// - -ChromeAppViewFactory::ChromeAppViewFactory( - winapp::Core::ICoreApplication* icore_app) { - mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app); - mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; - CheckHR(core_app.As(&app_exit)); - globals.app_exit = app_exit.Detach(); -} - -IFACEMETHODIMP -ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { - *view = mswr::Make<ChromeAppViewAsh>().Detach(); - return (*view) ? S_OK : E_OUTOFMEMORY; -} diff --git a/win8/metro_driver/chrome_app_view_ash.h b/win8/metro_driver/chrome_app_view_ash.h deleted file mode 100644 index ffe1d7e..0000000 --- a/win8/metro_driver/chrome_app_view_ash.h +++ /dev/null @@ -1,262 +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 WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ -#define WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ - -#include <stdint.h> -#include <windows.applicationmodel.core.h> -#include <windows.ui.core.h> -#include <windows.ui.input.h> -#include <windows.ui.viewmanagement.h> - -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string16.h" -#include "base/threading/thread.h" -#include "ipc/ipc_listener.h" -#include "ui/events/event_constants.h" -#include "win8/metro_driver/direct3d_helper.h" -#include "win8/metro_driver/ime/ime_popup_observer.h" -#include "win8/metro_driver/ime/input_source_observer.h" -#include "win8/metro_driver/ime/text_service_delegate.h" - -namespace base { -class FilePath; -} - -namespace IPC { -class Listener; -class ChannelProxy; -} - -namespace metro_driver { -class InputSource; -class TextService; -} - -namespace metro_viewer { -struct CharacterBounds; -struct UnderlineInfo; -} - -class OpenFilePickerSession; -class SaveFilePickerSession; -class FolderPickerSession; -class FilePickerSessionBase; - -struct MetroViewerHostMsg_SaveAsDialogParams; - -enum MetroTerminateMethod { - TERMINATE_USING_KEY_SEQUENCE = 1, - TERMINATE_USING_PROCESS_EXIT = 2, -}; - -class ChromeAppViewAsh - : public mswr::RuntimeClass<winapp::Core::IFrameworkView>, - public metro_driver::ImePopupObserver, - public metro_driver::InputSourceObserver, - public metro_driver::TextServiceDelegate { - public: - ChromeAppViewAsh(); - ~ChromeAppViewAsh() override; - - // IViewProvider overrides. - IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view) override; - IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window) override; - IFACEMETHOD(Load)(HSTRING entryPoint) override; - IFACEMETHOD(Run)() override; - IFACEMETHOD(Uninitialize)() override; - - // Helper function to unsnap the chrome metro app if it is snapped. - // Returns S_OK on success. - static HRESULT Unsnap(); - - void OnActivateDesktop(const base::FilePath& file_path, bool ash_exit); - void OnOpenURLOnDesktop(const base::FilePath& shortcut, - const base::string16& url); - void OnSetCursor(HCURSOR cursor); - void OnDisplayFileOpenDialog(const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path, - bool allow_multiple_files); - void OnDisplayFileSaveAsDialog( - const MetroViewerHostMsg_SaveAsDialogParams& params); - void OnDisplayFolderPicker(const base::string16& title); - void OnSetCursorPos(int x, int y); - - // This function is invoked when the open file operation completes. The - // result of the operation is passed in along with the OpenFilePickerSession - // instance which is deleted after we read the required information from - // the OpenFilePickerSession class. - void OnOpenFileCompleted(OpenFilePickerSession* open_file_picker, - bool success); - - // This function is invoked when the save file operation completes. The - // result of the operation is passed in along with the SaveFilePickerSession - // instance which is deleted after we read the required information from - // the SaveFilePickerSession class. - void OnSaveFileCompleted(SaveFilePickerSession* save_file_picker, - bool success); - - // This function is invoked when the folder picker operation completes. The - // result of the operation is passed in along with the FolderPickerSession - // instance which is deleted after we read the required information from - // the FolderPickerSession class. - void OnFolderPickerCompleted(FolderPickerSession* folder_picker, - bool success); - - void OnImeCancelComposition(); - void OnImeUpdateTextInputClient( - const std::vector<int32_t>& input_scopes, - const std::vector<metro_viewer::CharacterBounds>& character_bounds); - - void OnMetroExit(MetroTerminateMethod method); - - HWND core_window_hwnd() const { return core_window_hwnd_; } - - - private: - class PointerInfoHandler; - - // ImePopupObserver overrides. - void OnImePopupChanged(ImePopupObserver::EventType event) override; - - // InputSourceObserver overrides. - void OnInputSourceChanged() override; - - // TextServiceDelegate overrides. - void OnCompositionChanged( - const base::string16& text, - int32_t selection_start, - int32_t selection_end, - const std::vector<metro_viewer::UnderlineInfo>& underlines) override; - void OnTextCommitted(const base::string16& text) override; - - // Convenience for sending a MetroViewerHostMsg_MouseButton with the specified - // parameters. - void SendMouseButton(int x, - int y, - int extra, - ui::EventType event_type, - uint32_t flags, - ui::EventFlags changed_button, - bool is_horizontal_wheel); - - // Win8 only generates a mouse press for the initial button that goes down and - // a release when the last button is released. Any intermediary presses (or - // releases) do not result in a new press/release event. Instead a move is - // generated with the winui::Input::PointerUpdateKind identifying what - // changed. This function generates the necessary intermediary events (as - // necessary). - void GenerateMouseEventFromMoveIfNecessary(const PointerInfoHandler& pointer); - - HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, - winapp::Activation::IActivatedEventArgs* args); - - HRESULT OnPointerMoved(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnPointerPressed(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnPointerReleased(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnWheel(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnKeyDown(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args); - - HRESULT OnKeyUp(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args); - - // Invoked for system keys like Alt, etc. - HRESULT OnAcceleratorKeyDown(winui::Core::ICoreDispatcher* sender, - winui::Core::IAcceleratorKeyEventArgs* args); - - HRESULT OnCharacterReceived(winui::Core::ICoreWindow* sender, - winui::Core::ICharacterReceivedEventArgs* args); - - HRESULT OnWindowActivated(winui::Core::ICoreWindow* sender, - winui::Core::IWindowActivatedEventArgs* args); - - // Helper to handle search requests received via the search charm in ASH. - HRESULT HandleSearchRequest(winapp::Activation::IActivatedEventArgs* args); - // Helper to handle http/https url requests in ASH. - HRESULT HandleProtocolRequest(winapp::Activation::IActivatedEventArgs* args); - - HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args); - - // Tasks posted to the UI thread to initiate the search/url navigation - // requests. - void OnSearchRequest(const base::string16& search_string); - void OnNavigateToUrl(const base::string16& url); - - HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args); - - // This function checks if the Chrome browser channel is initialized. If yes - // then it goes ahead and starts up the viewer in Chrome OS mode. If not it - // posts a delayed task and checks again. It does this for a duration of 10 - // seconds and then bails. - void StartChromeOSMode(); - - mswr::ComPtr<winui::Core::ICoreWindow> window_; - mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; - EventRegistrationToken activated_token_; - EventRegistrationToken pointermoved_token_; - EventRegistrationToken pointerpressed_token_; - EventRegistrationToken pointerreleased_token_; - EventRegistrationToken wheel_token_; - EventRegistrationToken keydown_token_; - EventRegistrationToken keyup_token_; - EventRegistrationToken character_received_token_; - EventRegistrationToken accel_keydown_token_; - EventRegistrationToken accel_keyup_token_; - EventRegistrationToken window_activated_token_; - EventRegistrationToken sizechange_token_; - EventRegistrationToken edgeevent_token_; - - // Keep state about which button is currently down, if any, as PointerMoved - // events do not contain that state, but Ash's MouseEvents need it. Value is - // as a bitmask of ui::EventFlags. - uint32_t mouse_down_flags_; - - // Set the D3D swap chain and nothing else. - metro_driver::Direct3DHelper direct3d_helper_; - - // The IPC channel IO thread. - scoped_ptr<base::Thread> io_thread_; - - // The channel to Chrome, in particular to the MetroViewerProcessHost. - scoped_ptr<IPC::ChannelProxy> ui_channel_; - - // The actual window behind the view surface. - HWND core_window_hwnd_; - - // UI message loop to allow message passing into this thread. - base::MessageLoopForUI ui_loop_; - - // For IME support. - scoped_ptr<metro_driver::InputSource> input_source_; - scoped_ptr<metro_driver::TextService> text_service_; - - // The metro device scale factor as reported by the winrt interfaces. - float metro_dpi_scale_; - // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to - // ui/gfx/win/dpi.cc for more information. - float win32_dpi_scale_; - - // The cursor set by the chroem browser process. - HCURSOR last_cursor_; - - // Pointer to the channel listener for the channel between the viewer and - // the browser. - IPC::Listener* channel_listener_; -}; - -#endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ diff --git a/win8/metro_driver/file_picker.cc b/win8/metro_driver/file_picker.cc deleted file mode 100644 index 708b338..0000000 --- a/win8/metro_driver/file_picker.cc +++ /dev/null @@ -1,622 +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 "stdafx.h" -#include "win8/metro_driver/file_picker.h" - -#include <stddef.h> -#include <stdint.h> -#include <windows.storage.pickers.h> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string_util.h" -#include "base/synchronization/waitable_event.h" -#include "base/win/metro.h" -#include "base/win/scoped_comptr.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -namespace winstorage = ABI::Windows::Storage; -typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; - -// TODO(siggi): Complete this implementation and move it to a common place. -class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { - public: - ~StringVectorImpl() { - std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); - } - - HRESULT RuntimeClassInitialize(const std::vector<base::string16>& list) { - for (size_t i = 0; i < list.size(); ++i) - strings_.push_back(MakeHString(list[i])); - - return S_OK; - } - - // IVector<HSTRING> implementation. - STDMETHOD(GetAt)(unsigned index, HSTRING* item) { - if (index >= strings_.size()) - return E_INVALIDARG; - - return ::WindowsDuplicateString(strings_[index], item); - } - STDMETHOD(get_Size)(unsigned *size) { - if (strings_.size() > UINT_MAX) - return E_UNEXPECTED; - *size = static_cast<unsigned>(strings_.size()); - return S_OK; - } - STDMETHOD(GetView)(winfoundtn::Collections::IVectorView<HSTRING> **view) { - return E_NOTIMPL; - } - STDMETHOD(IndexOf)(HSTRING value, unsigned *index, boolean *found) { - return E_NOTIMPL; - } - - // write methods - STDMETHOD(SetAt)(unsigned index, HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(InsertAt)(unsigned index, HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(RemoveAt)(unsigned index) { - return E_NOTIMPL; - } - STDMETHOD(Append)(HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(RemoveAtEnd)() { - return E_NOTIMPL; - } - STDMETHOD(Clear)() { - return E_NOTIMPL; - } - - private: - std::vector<HSTRING> strings_; -}; - -class FilePickerSessionBase { - public: - // Creates a file picker for open_file_name. - explicit FilePickerSessionBase(OPENFILENAME* open_file_name); - - // Runs the picker, returns true on success. - bool Run(); - - protected: - // Creates, configures and starts a file picker. - // If the HRESULT returned is a failure code the file picker has not started, - // so no callbacks should be expected. - virtual HRESULT StartFilePicker() = 0; - - // The parameters to our picker. - OPENFILENAME* open_file_name_; - // The event Run waits on. - base::WaitableEvent event_; - // True iff a file picker has successfully finished. - bool success_; - - private: - // Initiate a file picker, must be called on the metro dispatcher's thread. - void DoFilePicker(); - - DISALLOW_COPY_AND_ASSIGN(FilePickerSessionBase); -}; - -class OpenFilePickerSession : public FilePickerSessionBase { - public: - explicit OpenFilePickerSession(OPENFILENAME* open_file_name); - - private: - HRESULT StartFilePicker() override; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> - SingleFileAsyncOp; - typedef winfoundtn::Collections::IVectorView< - winstorage::StorageFile*> StorageFileVectorCollection; - typedef winfoundtn::IAsyncOperation<StorageFileVectorCollection*> - MultiFileAsyncOp; - - // Called asynchronously when a single file picker is done. - HRESULT SinglePickerDone(SingleFileAsyncOp* async, AsyncStatus status); - - // Called asynchronously when a multi file picker is done. - HRESULT MultiPickerDone(MultiFileAsyncOp* async, AsyncStatus status); - - // Composes a multi-file result string suitable for returning to a - // from a storage file collection. - static HRESULT ComposeMultiFileResult(StorageFileVectorCollection* files, - base::string16* result); - private: - DISALLOW_COPY_AND_ASSIGN(OpenFilePickerSession); -}; - -class SaveFilePickerSession : public FilePickerSessionBase { - public: - explicit SaveFilePickerSession(OPENFILENAME* open_file_name); - - private: - HRESULT StartFilePicker() override; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> - SaveFileAsyncOp; - - // Called asynchronously when the save file picker is done. - HRESULT FilePickerDone(SaveFileAsyncOp* async, AsyncStatus status); -}; - -FilePickerSessionBase::FilePickerSessionBase(OPENFILENAME* open_file_name) - : open_file_name_(open_file_name), - event_(true, false), - success_(false) { -} - -bool FilePickerSessionBase::Run() { - DCHECK(globals.appview_msg_loop != NULL); - - // Post the picker request over to the metro thread. - bool posted = globals.appview_msg_loop->PostTask(FROM_HERE, - base::Bind(&FilePickerSessionBase::DoFilePicker, base::Unretained(this))); - if (!posted) - return false; - - // Wait for the file picker to complete. - event_.Wait(); - - return success_; -} - -void FilePickerSessionBase::DoFilePicker() { - // The file picker will fail if spawned from a snapped application, - // so let's attempt to unsnap first if we're in that state. - HRESULT hr = ChromeAppView::Unsnap(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to unsnap for file picker, error 0x" << hr; - } - - if (SUCCEEDED(hr)) - hr = StartFilePicker(); - - if (FAILED(hr)) { - LOG(ERROR) << "Failed to start file picker, error 0x" - << std::hex << hr; - - event_.Signal(); - } -} - -OpenFilePickerSession::OpenFilePickerSession(OPENFILENAME* open_file_name) - : FilePickerSessionBase(open_file_name) { -} - -HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - UINT32 path_len = 0; - const wchar_t* path_str = - ::WindowsGetStringRawBuffer(file_path.Get(), &path_len); - - // If the selected file name is longer than the supplied buffer, - // we return false as per GetOpenFileName documentation. - if (path_len < open_file_name_->nMaxFile) { - base::wcslcpy(open_file_name_->lpstrFile, - path_str, - open_file_name_->nMaxFile); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - - event_.Signal(); - - return S_OK; -} - -HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<StorageFileVectorCollection> files; - HRESULT hr = async->GetResults(files.GetAddressOf()); - - if (files) { - base::string16 result; - if (SUCCEEDED(hr)) - hr = ComposeMultiFileResult(files.Get(), &result); - - if (SUCCEEDED(hr)) { - if (result.size() + 1 < open_file_name_->nMaxFile) { - // Because the result has embedded nulls, we must memcpy. - memcpy(open_file_name_->lpstrFile, - result.c_str(), - (result.size() + 1) * sizeof(result[0])); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL StorageFileVectorCollection"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - - event_.Signal(); - - return S_OK; -} - -HRESULT OpenFilePickerSession::StartFilePicker() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - DCHECK(open_file_name_ != NULL); - - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileOpenPicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileOpenPicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - // Set the file type filter - mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter; - hr = picker->get_FileTypeFilter(filter.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (open_file_name_->lpstrFilter == NULL) { - hr = filter->Append(mswrw::HStringReference(L"*").Get()); - if (FAILED(hr)) - return hr; - } else { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = open_file_name_->lpstrFilter; - while (*walk != L'\0') { - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<base::string16> extensions_win32_style = base::SplitString( - walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - // Metro wants suffixes only, not patterns. - mswrw::HString extension; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - if (extensions_win32_style[i] == L"*.*") { - // The wildcard filter is "*" for Metro. The string "*.*" produces - // an "invalid parameter" error. - hr = extension.Set(L"*"); - } else { - // Metro wants suffixes only, not patterns. - base::string16 ext = - base::FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != base::string16::npos)) { - continue; - } - hr = extension.Set(ext.c_str()); - } - if (SUCCEEDED(hr)) - hr = filter->Append(extension.Get()); - if (FAILED(hr)) - return hr; - } - - // Walk past the extension. - walk += wcslen(walk) + 1; - } - } - - // Spin up a single or multi picker as appropriate. - if (open_file_name_->Flags & OFN_ALLOWMULTISELECT) { - mswr::ComPtr<MultiFileAsyncOp> completion; - hr = picker->PickMultipleFilesAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - StorageFileVectorCollection*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::MultiPickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } else { - mswr::ComPtr<SingleFileAsyncOp> completion; - hr = picker->PickSingleFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::SinglePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } -} - -HRESULT OpenFilePickerSession::ComposeMultiFileResult( - StorageFileVectorCollection* files, base::string16* result) { - DCHECK(files != NULL); - DCHECK(result != NULL); - - // Empty the output string. - result->clear(); - - unsigned int num_files = 0; - HRESULT hr = files->get_Size(&num_files); - if (FAILED(hr)) - return hr; - - // Make sure we return an error on an empty collection. - if (num_files == 0) { - DLOG(ERROR) << "Empty collection on input."; - return E_UNEXPECTED; - } - - // This stores the base path that should be the parent of all the files. - base::FilePath base_path; - - // Iterate through the collection and append the file paths to the result. - for (unsigned int i = 0; i < num_files; ++i) { - mswr::ComPtr<winstorage::IStorageFile> file; - hr = files->GetAt(i, file.GetAddressOf()); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<winstorage::IStorageItem> storage_item; - hr = file.As(&storage_item); - if (FAILED(hr)) - return hr; - - mswrw::HString file_path_str; - hr = storage_item->get_Path(file_path_str.GetAddressOf()); - if (FAILED(hr)) - return hr; - - base::FilePath file_path(MakeStdWString(file_path_str.Get())); - if (base_path.empty()) { - DCHECK(result->empty()); - base_path = file_path.DirName(); - - // Append the path, including the terminating zero. - // We do this only for the first file. - result->append(base_path.value().c_str(), base_path.value().size() + 1); - } - DCHECK(!result->empty()); - DCHECK(!base_path.empty()); - DCHECK(base_path == file_path.DirName()); - - // Append the base name, including the terminating zero. - base::FilePath base_name = file_path.BaseName(); - result->append(base_name.value().c_str(), base_name.value().size() + 1); - } - - DCHECK(!result->empty()); - - return S_OK; -} - -SaveFilePickerSession::SaveFilePickerSession(OPENFILENAME* open_file_name) - : FilePickerSessionBase(open_file_name) { -} - -HRESULT SaveFilePickerSession::StartFilePicker() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - DCHECK(open_file_name_ != NULL); - - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileSavePicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileSavePicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - typedef winfoundtn::Collections::IMap<HSTRING, StringVectorItf*> - StringVectorMap; - mswr::ComPtr<StringVectorMap> choices; - hr = picker->get_FileTypeChoices(choices.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (open_file_name_->lpstrFilter) { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension list}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = open_file_name_->lpstrFilter; - while (*walk != L'\0') { - mswrw::HString description; - hr = description.Set(walk); - if (FAILED(hr)) - return hr; - - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<base::string16> extensions_win32_style = base::SplitString( - walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - // Metro wants suffixes only, not patterns. Also, metro does not support - // the all files ("*") pattern in the save picker. - std::vector<base::string16> extensions; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - base::string16 ext = - base::FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != base::string16::npos)) - continue; - extensions.push_back(ext); - } - - if (!extensions.empty()) { - // Convert to a Metro collection class. - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), extensions); - if (FAILED(hr)) - return hr; - - // Finally set the filter. - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - // Walk past the extension(s). - walk += wcslen(walk) + 1; - } - } - - // The save picker requires at least one choice. Callers are strongly advised - // to provide sensible choices. If none were given, fallback to .dat. - uint32_t num_choices = 0; - hr = choices->get_Size(&num_choices); - if (FAILED(hr)) - return hr; - - if (num_choices == 0) { - mswrw::HString description; - // TODO(grt): Get a properly translated string. This can't be done from - // within metro_driver. Consider preprocessing the filter list in Chrome - // land to ensure it has this entry if all others are patterns. In that - // case, this whole block of code can be removed. - hr = description.Set(L"Data File"); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), std::vector<base::string16>(1, L".dat")); - if (FAILED(hr)) - return hr; - - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - if (open_file_name_->lpstrFile != NULL) { - hr = picker->put_SuggestedFileName( - mswrw::HStringReference( - const_cast<const wchar_t*>(open_file_name_->lpstrFile)).Get()); - if (FAILED(hr)) - return hr; - } - - mswr::ComPtr<SaveFileAsyncOp> completion; - hr = picker->PickSaveFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &SaveFilePickerSession::FilePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; -} - -HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - base::string16 path_str = MakeStdWString(file_path.Get()); - - // If the selected file name is longer than the supplied buffer, - // we return false as per GetOpenFileName documentation. - if (path_str.size() < open_file_name_->nMaxFile) { - base::wcslcpy(open_file_name_->lpstrFile, - path_str.c_str(), - open_file_name_->nMaxFile); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - - event_.Signal(); - - return S_OK; -} - -} // namespace - -BOOL MetroGetOpenFileName(OPENFILENAME* open_file_name) { - OpenFilePickerSession session(open_file_name); - - return session.Run(); -} - -BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name) { - SaveFilePickerSession session(open_file_name); - - return session.Run(); -} diff --git a/win8/metro_driver/file_picker.h b/win8/metro_driver/file_picker.h deleted file mode 100644 index ef56cb3..0000000 --- a/win8/metro_driver/file_picker.h +++ /dev/null @@ -1,18 +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 CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ - -#include <commdlg.h> - -// This function behaves similarly to GetOpenFileName, except it uses a -// Metro file picker to pick a single or multiple file names. -extern "C" __declspec(dllexport) -BOOL MetroGetOpenFileName(OPENFILENAME* open_file_name); - -extern "C" __declspec(dllexport) -BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ - diff --git a/win8/metro_driver/file_picker_ash.cc b/win8/metro_driver/file_picker_ash.cc deleted file mode 100644 index 31e699d..0000000 --- a/win8/metro_driver/file_picker_ash.cc +++ /dev/null @@ -1,619 +0,0 @@ -// 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 <stddef.h> -#include <stdint.h> - -#include "stdafx.h" -#include "win8/metro_driver/file_picker_ash.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/synchronization/waitable_event.h" -#include "base/win/scoped_comptr.h" -#include "ui/metro_viewer/metro_viewer_messages.h" -#include "win8/metro_driver/chrome_app_view_ash.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; - -// TODO(siggi): Complete this implementation and move it to a common place. -class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { - public: - ~StringVectorImpl() override { - std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); - } - - HRESULT RuntimeClassInitialize(const std::vector<base::string16>& list) { - for (size_t i = 0; i < list.size(); ++i) - strings_.push_back(MakeHString(list[i])); - - return S_OK; - } - - // IVector<HSTRING> implementation. - STDMETHOD(GetAt)(unsigned index, HSTRING* item) override { - if (index >= strings_.size()) - return E_INVALIDARG; - - return ::WindowsDuplicateString(strings_[index], item); - } - STDMETHOD(get_Size)(unsigned* size) override { - if (strings_.size() > UINT_MAX) - return E_UNEXPECTED; - *size = static_cast<unsigned>(strings_.size()); - return S_OK; - } - STDMETHOD(GetView)( - winfoundtn::Collections::IVectorView<HSTRING>** view) override { - return E_NOTIMPL; - } - STDMETHOD(IndexOf)(HSTRING value, unsigned* index, boolean* found) override { - return E_NOTIMPL; - } - - // write methods - STDMETHOD(SetAt)(unsigned index, HSTRING item) override { return E_NOTIMPL; } - STDMETHOD(InsertAt)(unsigned index, HSTRING item) override { - return E_NOTIMPL; - } - STDMETHOD(RemoveAt)(unsigned index) override { return E_NOTIMPL; } - STDMETHOD(Append)(HSTRING item) override { return E_NOTIMPL; } - STDMETHOD(RemoveAtEnd)() override { return E_NOTIMPL; } - STDMETHOD(Clear)() override { return E_NOTIMPL; } - - private: - std::vector<HSTRING> strings_; -}; - -} // namespace - -FilePickerSessionBase::~FilePickerSessionBase() { -} - -bool FilePickerSessionBase::Run() { - if (!DoFilePicker()) - return false; - return success_; -} - -FilePickerSessionBase::FilePickerSessionBase(ChromeAppViewAsh* app_view, - const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path) - : success_(false), - title_(title), - filter_(filter), - default_path_(default_path), - app_view_(app_view) { -} - -bool FilePickerSessionBase::DoFilePicker() { - // The file picker will fail if spawned from a snapped application, - // so let's attempt to unsnap first if we're in that state. - HRESULT hr = ChromeAppViewAsh::Unsnap(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to unsnap for file picker, error 0x" << hr; - return false; - } - hr = StartFilePicker(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to start file picker, error 0x" - << std::hex << hr; - return false; - } - return true; -} - -OpenFilePickerSession::OpenFilePickerSession( - ChromeAppViewAsh* app_view, - const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path, - bool allow_multi_select) - : FilePickerSessionBase(app_view, title, filter, default_path), - allow_multi_select_(allow_multi_select) { -} - -OpenFilePickerSession::~OpenFilePickerSession() { -} - -HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - UINT32 path_len = 0; - const wchar_t* path_str = - ::WindowsGetStringRawBuffer(file_path.Get(), &path_len); - - result_ = path_str; - success_ = true; - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - app_view_->OnOpenFileCompleted(this, success_); - return S_OK; -} - -HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<StorageFileVectorCollection> files; - HRESULT hr = async->GetResults(files.GetAddressOf()); - - if (files) { - base::string16 result; - if (SUCCEEDED(hr)) - hr = ComposeMultiFileResult(files.Get(), &result); - - if (SUCCEEDED(hr)) { - success_ = true; - // The code below has been copied from the - // SelectFileDialogImpl::RunOpenMultiFileDialog function in - // select_file_dialog_win.cc. - // TODO(ananta) - // Consolidate this into a common place. - const wchar_t* selection = result.c_str(); - std::vector<base::FilePath> files; - - while (*selection) { // Empty string indicates end of list. - files.push_back(base::FilePath(selection)); - // Skip over filename and null-terminator. - selection += files.back().value().length() + 1; - } - if (files.empty()) { - success_ = false; - } else if (files.size() == 1) { - // When there is one file, it contains the path and filename. - filenames_ = files; - } else if (files.size() > 1) { - // Otherwise, the first string is the path, and the remainder are - // filenames. - std::vector<base::FilePath>::iterator path = files.begin(); - for (std::vector<base::FilePath>::iterator file = path + 1; - file != files.end(); ++file) { - filenames_.push_back(path->Append(*file)); - } - } - } - } else { - LOG(ERROR) << "NULL StorageFileVectorCollection"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - app_view_->OnOpenFileCompleted(this, success_); - return S_OK; -} - -HRESULT OpenFilePickerSession::StartFilePicker() { - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileOpenPicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileOpenPicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - // Set the file type filter - mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter; - hr = picker->get_FileTypeFilter(filter.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (filter_.empty()) { - hr = filter->Append(mswrw::HStringReference(L"*").Get()); - if (FAILED(hr)) - return hr; - } else { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = filter_.c_str(); - while (*walk != L'\0') { - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<base::string16> extensions_win32_style = base::SplitString( - walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - // Metro wants suffixes only, not patterns. - mswrw::HString extension; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - if (extensions_win32_style[i] == L"*.*") { - // The wildcard filter is "*" for Metro. The string "*.*" produces - // an "invalid parameter" error. - hr = extension.Set(L"*"); - } else { - // Metro wants suffixes only, not patterns. - base::string16 ext = - base::FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != base::string16::npos)) { - continue; - } - hr = extension.Set(ext.c_str()); - } - if (SUCCEEDED(hr)) - hr = filter->Append(extension.Get()); - if (FAILED(hr)) - return hr; - } - - // Walk past the extension. - walk += wcslen(walk) + 1; - } - } - - // Spin up a single or multi picker as appropriate. - if (allow_multi_select_) { - mswr::ComPtr<MultiFileAsyncOp> completion; - hr = picker->PickMultipleFilesAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - StorageFileVectorCollection*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::MultiPickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } else { - mswr::ComPtr<SingleFileAsyncOp> completion; - hr = picker->PickSingleFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::SinglePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } -} - -HRESULT OpenFilePickerSession::ComposeMultiFileResult( - StorageFileVectorCollection* files, base::string16* result) { - DCHECK(files != NULL); - DCHECK(result != NULL); - - // Empty the output string. - result->clear(); - - unsigned int num_files = 0; - HRESULT hr = files->get_Size(&num_files); - if (FAILED(hr)) - return hr; - - // Make sure we return an error on an empty collection. - if (num_files == 0) { - DLOG(ERROR) << "Empty collection on input."; - return E_UNEXPECTED; - } - - // This stores the base path that should be the parent of all the files. - base::FilePath base_path; - - // Iterate through the collection and append the file paths to the result. - for (unsigned int i = 0; i < num_files; ++i) { - mswr::ComPtr<winstorage::IStorageFile> file; - hr = files->GetAt(i, file.GetAddressOf()); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<winstorage::IStorageItem> storage_item; - hr = file.As(&storage_item); - if (FAILED(hr)) - return hr; - - mswrw::HString file_path_str; - hr = storage_item->get_Path(file_path_str.GetAddressOf()); - if (FAILED(hr)) - return hr; - - base::FilePath file_path(MakeStdWString(file_path_str.Get())); - if (base_path.empty()) { - DCHECK(result->empty()); - base_path = file_path.DirName(); - - // Append the path, including the terminating zero. - // We do this only for the first file. - result->append(base_path.value().c_str(), base_path.value().size() + 1); - } - DCHECK(!result->empty()); - DCHECK(!base_path.empty()); - DCHECK(base_path == file_path.DirName()); - - // Append the base name, including the terminating zero. - base::FilePath base_name = file_path.BaseName(); - result->append(base_name.value().c_str(), base_name.value().size() + 1); - } - - DCHECK(!result->empty()); - - return S_OK; -} - -SaveFilePickerSession::SaveFilePickerSession( - ChromeAppViewAsh* app_view, - const MetroViewerHostMsg_SaveAsDialogParams& params) - : FilePickerSessionBase(app_view, - params.title, - params.filter, - params.suggested_name), - filter_index_(params.filter_index) { -} - -int SaveFilePickerSession::filter_index() const { - // TODO(ananta) - // Add support for returning the correct filter index. This does not work in - // regular Chrome metro on trunk as well. - // BUG: https://code.google.com/p/chromium/issues/detail?id=172704 - return filter_index_; -} - -HRESULT SaveFilePickerSession::StartFilePicker() { - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileSavePicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileSavePicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - typedef winfoundtn::Collections::IMap<HSTRING, StringVectorItf*> - StringVectorMap; - mswr::ComPtr<StringVectorMap> choices; - hr = picker->get_FileTypeChoices(choices.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (!filter_.empty()) { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension list}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = filter_.c_str(); - while (*walk != L'\0') { - mswrw::HString description; - hr = description.Set(walk); - if (FAILED(hr)) - return hr; - - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<base::string16> extensions_win32_style = base::SplitString( - walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - // Metro wants suffixes only, not patterns. Also, metro does not support - // the all files ("*") pattern in the save picker. - std::vector<base::string16> extensions; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - base::string16 ext = - base::FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != base::string16::npos)) - continue; - extensions.push_back(ext); - } - - if (!extensions.empty()) { - // Convert to a Metro collection class. - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), extensions); - if (FAILED(hr)) - return hr; - - // Finally set the filter. - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - // Walk past the extension(s). - walk += wcslen(walk) + 1; - } - } - - // The save picker requires at least one choice. Callers are strongly advised - // to provide sensible choices. If none were given, fallback to .dat. - uint32_t num_choices = 0; - hr = choices->get_Size(&num_choices); - if (FAILED(hr)) - return hr; - - if (num_choices == 0) { - mswrw::HString description; - // TODO(grt): Get a properly translated string. This can't be done from - // within metro_driver. Consider preprocessing the filter list in Chrome - // land to ensure it has this entry if all others are patterns. In that - // case, this whole block of code can be removed. - hr = description.Set(L"Data File"); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), std::vector<base::string16>(1, L".dat")); - if (FAILED(hr)) - return hr; - - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - if (!default_path_.empty()) { - base::string16 file_part = default_path_.BaseName().value(); - // If the suggested_name is a root directory, then don't set it as the - // suggested name. - if (file_part.size() == 1 && file_part[0] == L'\\') - file_part.clear(); - hr = picker->put_SuggestedFileName( - mswrw::HStringReference(file_part.c_str()).Get()); - if (FAILED(hr)) - return hr; - } - - mswr::ComPtr<SaveFileAsyncOp> completion; - hr = picker->PickSaveFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &SaveFilePickerSession::FilePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; -} - -HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - base::string16 path_str = MakeStdWString(file_path.Get()); - result_ = path_str; - success_ = true; - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - app_view_->OnSaveFileCompleted(this, success_); - return S_OK; -} - -FolderPickerSession::FolderPickerSession(ChromeAppViewAsh* app_view, - const base::string16& title) - : FilePickerSessionBase(app_view, title, L"", base::FilePath()) { -} - -HRESULT FolderPickerSession::StartFilePicker() { - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FolderPicker); - - // Create the folder picker. - mswr::ComPtr<winstorage::Pickers::IFolderPicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - // Set the file type filter - mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter; - hr = picker->get_FileTypeFilter(filter.GetAddressOf()); - if (FAILED(hr)) - return hr; - - hr = filter->Append(mswrw::HStringReference(L"*").Get()); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<FolderPickerAsyncOp> completion; - hr = picker->PickSingleFolderAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFolder*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &FolderPickerSession::FolderPickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - return hr; -} - -HRESULT FolderPickerSession::FolderPickerDone(FolderPickerAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFolder> folder; - HRESULT hr = async->GetResults(folder.GetAddressOf()); - - if (folder) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = folder.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - base::string16 path_str = MakeStdWString(file_path.Get()); - result_ = path_str; - success_ = true; - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << static_cast<int>(status); - } - app_view_->OnFolderPickerCompleted(this, success_); - return S_OK; -} - diff --git a/win8/metro_driver/file_picker_ash.h b/win8/metro_driver/file_picker_ash.h deleted file mode 100644 index 5d41a83..0000000 --- a/win8/metro_driver/file_picker_ash.h +++ /dev/null @@ -1,157 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_ASH_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_ASH_H_ - -#include <vector> - -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/strings/string16.h" - -class ChromeAppViewAsh; -struct MetroViewerHostMsg_SaveAsDialogParams; - -namespace base { -class FilePath; -} - -// Base class for the file pickers. -class FilePickerSessionBase { - public: - virtual ~FilePickerSessionBase(); - - // Runs the picker, returns true on success. - bool Run(); - - const base::string16& result() const { return result_; } - - bool success() const { return success_; } - - protected: - // Creates a file picker for open_file_name. - FilePickerSessionBase(ChromeAppViewAsh* app_view, - const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path); - - // Creates, configures and starts a file picker. - // If the HRESULT returned is a failure code the file picker has not started, - // so no callbacks should be expected. - virtual HRESULT StartFilePicker() = 0; - - // True iff a file picker has successfully finished. - bool success_; - - // The title of the file picker. - base::string16 title_; - - // The file type filter. - base::string16 filter_; - - // The starting directory/file name. - base::FilePath default_path_; - - // Pointer to the ChromeAppViewAsh instance. We notify the ChromeAppViewAsh - // instance when the file open/save operations complete. - ChromeAppViewAsh* app_view_; - - base::string16 result_; - - private: - // Initiate a file picker, must be called on the main metro thread. - // Returns true on success. - bool DoFilePicker(); - - DISALLOW_COPY_AND_ASSIGN(FilePickerSessionBase); -}; - -// Provides functionality to display the open file/multiple open file pickers -// metro dialog. -class OpenFilePickerSession : public FilePickerSessionBase { - public: - OpenFilePickerSession(ChromeAppViewAsh* app_view, - const base::string16& title, - const base::string16& filter, - const base::FilePath& default_path, - bool allow_multi_select); - ~OpenFilePickerSession() override; - - const std::vector<base::FilePath>& filenames() const { - return filenames_; - } - - bool allow_multi_select() const { return allow_multi_select_; } - - private: - HRESULT StartFilePicker() override; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> - SingleFileAsyncOp; - typedef winfoundtn::Collections::IVectorView< - winstorage::StorageFile*> StorageFileVectorCollection; - typedef winfoundtn::IAsyncOperation<StorageFileVectorCollection*> - MultiFileAsyncOp; - - // Called asynchronously when a single file picker is done. - HRESULT SinglePickerDone(SingleFileAsyncOp* async, AsyncStatus status); - - // Called asynchronously when a multi file picker is done. - HRESULT MultiPickerDone(MultiFileAsyncOp* async, AsyncStatus status); - - // Composes a multi-file result string suitable for returning to a - // from a storage file collection. - static HRESULT ComposeMultiFileResult(StorageFileVectorCollection* files, - base::string16* result); - - // True if the multi file picker is to be displayed. - bool allow_multi_select_; - // If multi select is true then this member contains the list of filenames - // to be returned back. - std::vector<base::FilePath> filenames_; - - DISALLOW_COPY_AND_ASSIGN(OpenFilePickerSession); -}; - -// Provides functionality to display the save file picker. -class SaveFilePickerSession : public FilePickerSessionBase { - public: - SaveFilePickerSession(ChromeAppViewAsh* app_view, - const MetroViewerHostMsg_SaveAsDialogParams& params); - - int filter_index() const; - - private: - HRESULT StartFilePicker() override; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> SaveFileAsyncOp; - - // Called asynchronously when the save file picker is done. - HRESULT FilePickerDone(SaveFileAsyncOp* async, AsyncStatus status); - - int filter_index_; - - DISALLOW_COPY_AND_ASSIGN(SaveFilePickerSession); -}; - -// Provides functionality to display the folder picker. -class FolderPickerSession : public FilePickerSessionBase { - public: - FolderPickerSession(ChromeAppViewAsh* app_view, const base::string16& title); - - private: - HRESULT StartFilePicker() override; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFolder*> - FolderPickerAsyncOp; - - // Called asynchronously when the folder picker is done. - HRESULT FolderPickerDone(FolderPickerAsyncOp* async, AsyncStatus status); - - DISALLOW_COPY_AND_ASSIGN(FolderPickerSession); -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_ASH_H_ - diff --git a/win8/metro_driver/metro_driver.cc b/win8/metro_driver/metro_driver.cc deleted file mode 100644 index 650b238..0000000 --- a/win8/metro_driver/metro_driver.cc +++ /dev/null @@ -1,135 +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 "stdafx.h" -#include "win8/metro_driver/metro_driver.h" - -#include <roerrorapi.h> -#include <shobjidl.h> - -#include "base/at_exit.h" -#include "base/command_line.h" -#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" - -namespace { - -#if !defined(NDEBUG) -LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) { - // See roerrorapi.h for a description of the - // exception codes and parameters. - DWORD code = ex_info->ExceptionRecord->ExceptionCode; - ULONG_PTR* info = ex_info->ExceptionRecord->ExceptionInformation; - if (code == EXCEPTION_RO_ORIGINATEERROR) { - base::string16 msg(reinterpret_cast<wchar_t*>(info[2]), info[1]); - LOG(ERROR) << "VEH: Metro error 0x" << std::hex << info[0] << ": " << msg; - } else if (code == EXCEPTION_RO_TRANSFORMERROR) { - base::string16 msg(reinterpret_cast<wchar_t*>(info[3]), info[2]); - LOG(ERROR) << "VEH: Metro old error 0x" << std::hex << info[0] - << " new error 0x" << info[1] << ": " << msg; - } - - return EXCEPTION_CONTINUE_SEARCH; -} -#endif - -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} -const GUID kChromeTraceProviderName = { - 0x7fe69228, 0x633e, 0x4f06, - { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; - -} // namespace - -#if !defined(COMPONENT_BUILD) -// Required for base initialization. -// TODO(siggi): This should be handled better, as this way our at exit -// registrations will run under the loader's lock. However, -// once metro_driver is merged into Chrome.dll, this will go away anyhow. -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. - base::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); - HANDLE registration = - ::AddVectoredExceptionHandler(TRUE, ErrorReportingHandler); -#endif - // Enable trace control and transport through event tracing for Windows. - logging::LogEventProvider::Initialize(kChromeTraceProviderName); - DVLOG(1) << "InitMetro"; - - // OS specific initialization. - mswr::ComPtr<winapp::Core::ICoreApplication> core_app; - if (base::win::GetVersion() < base::win::VERSION_WIN8) - core_app = InitWindows7(); - else - core_app = InitWindows8(); - - auto view_factory = mswr::Make<ChromeAppViewFactory>(core_app.Get()); - HRESULT hr = core_app->Run(view_factory.Get()); - DVLOG(1) << "exiting InitMetro, hr=" << hr; - -#if !defined(NDEBUG) - ::RemoveVectoredExceptionHandler(registration); -#endif - return hr; -} - -// Activates the application known by |app_id|. Returns, among other things, -// E_APPLICATION_NOT_REGISTERED if |app_id| identifies Chrome and Chrome is not -// the default browser. -extern "C" __declspec(dllexport) -HRESULT ActivateApplication(const wchar_t* app_id) { - base::win::ScopedComPtr<IApplicationActivationManager> activator; - HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); - if (SUCCEEDED(hr)) { - DWORD pid = 0; - hr = activator->ActivateApplication(app_id, L"", AO_NONE, &pid); - } - return hr; -} diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index caa5ab5..a6f9afa 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -65,9 +65,6 @@ 'sources': [ 'display_properties.cc', 'display_properties.h', - 'metro_driver.cc', - 'metro_driver.h', - 'metro_driver_win7.cc', 'stdafx.h', 'winrt_utils.cc', 'winrt_utils.h', @@ -75,16 +72,9 @@ ], 'conditions': [ ['use_aura==1', { - 'dependencies': [ - '../win8.gyp:metro_viewer_constants', - ], 'sources': [ - 'chrome_app_view_ash.cc', - 'chrome_app_view_ash.h', 'direct3d_helper.cc', 'direct3d_helper.h', - 'file_picker_ash.cc', - 'file_picker_ash.h', ], 'includes': [ 'ime/ime.gypi', @@ -97,8 +87,6 @@ 'chrome_url_launch_handler.h', 'devices_handler.cc', 'devices_handler.h', - 'file_picker.cc', - 'file_picker.h', 'metro_dialog_box.cc', 'metro_dialog_box.h', 'print_document_source.cc', diff --git a/win8/metro_driver/metro_driver.h b/win8/metro_driver/metro_driver.h deleted file mode 100644 index da8f1c6..0000000 --- a/win8/metro_driver/metro_driver.h +++ /dev/null @@ -1,17 +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 WIN8_METRO_DRIVER_METRO_DRIVER_H_ -#define WIN8_METRO_DRIVER_METRO_DRIVER_H_ - -#include "stdafx.h" - -class ChromeAppViewFactory - : public mswr::RuntimeClass<winapp::Core::IFrameworkViewSource> { - public: - ChromeAppViewFactory(winapp::Core::ICoreApplication* icore_app); - IFACEMETHOD(CreateView)(winapp::Core::IFrameworkView** view) override; -}; - -#endif // WIN8_METRO_DRIVER_METRO_DRIVER_H_
\ No newline at end of file diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc deleted file mode 100644 index 62662f5..0000000 --- a/win8/metro_driver/metro_driver_win7.cc +++ /dev/null @@ -1,1229 +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 "stdafx.h" -#include <corewindow.h> -#include <shobjidl.h> -#include <stdint.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "ui/gfx/geometry/safe_integer_conversions.h" -#include "ui/gfx/win/msg_util.h" - -#pragma comment(lib, "shell32.lib") - -EXTERN_C IMAGE_DOS_HEADER __ImageBase; -// Even though we only create a single window, we need to keep this -// count because of the hidden window used by the UI message loop of -// the metro viewer. -int g_window_count = 0; - -const wchar_t kAshWin7AppId[] = L"Google.Chrome.AshWin7.1"; -const wchar_t kAshWin7CoreWindowHandler[] = L"CoreWindowHandler"; -extern float GetModernUIScale(); -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, - LPARAM lparam); - -HWND CreateMetroTopLevelWindow(const RECT& work_area) { - 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 = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME"); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1); - wcex.lpszMenuName = 0; - wcex.lpszClassName = L"Windows.UI.Core.CoreWindow"; - wcex.hIconSm = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME"); - - HWND hwnd = ::CreateWindowExW(0, - MAKEINTATOM(::RegisterClassExW(&wcex)), - L"metro_win7", - WS_POPUP | WS_VISIBLE | WS_MINIMIZEBOX, - work_area.top, work_area.left, - work_area.right, work_area.bottom, - NULL, NULL, hInst, NULL); - return hwnd; -} - -typedef winfoundtn::ITypedEventHandler< - winapp::Core::CoreApplicationView*, - winapp::Activation::IActivatedEventArgs*> ActivatedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler; - -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; - -// This interface is implemented by classes which handle mouse and keyboard -// input. -class InputHandler { - public: - InputHandler() {} - virtual ~InputHandler() {} - - virtual bool HandleKeyboardMessage(const MSG& msg) = 0; - virtual bool HandleMouseMessage(const MSG& msg) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(InputHandler); -}; - -// This class implements the winrt interfaces corresponding to mouse input. -class MouseEvent : public mswr::RuntimeClass< - winui::Core::IPointerEventArgs, - winui::Input::IPointerPoint, - winui::Input::IPointerPointProperties, - windevs::Input::IPointerDevice> { - public: - MouseEvent(const MSG& msg) - : msg_(msg) { - } - - // IPointerEventArgs implementation. - HRESULT STDMETHODCALLTYPE - get_CurrentPoint(winui::Input::IPointerPoint** point) override { - return QueryInterface(winui::Input::IID_IPointerPoint, - reinterpret_cast<void**>(point)); - } - - HRESULT STDMETHODCALLTYPE - get_KeyModifiers(winsys::VirtualKeyModifiers* modifiers) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE GetIntermediatePoints( - winfoundtn::Collections::IVector<winui::Input::PointerPoint*>** points) - override { - return E_NOTIMPL; - } - - // IPointerPoint implementation. - HRESULT STDMETHODCALLTYPE - get_PointerDevice(windevs::Input::IPointerDevice** pointer_device) override { - return QueryInterface(windevs::Input::IID_IPointerDevice, - reinterpret_cast<void**>(pointer_device)); - } - - HRESULT STDMETHODCALLTYPE get_Position(winfoundtn::Point* position) override { - static float scale = GetModernUIScale(); - // Scale down the points here as they are scaled up on the other side. - position->X = gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_.lParam) / scale); - position->Y = gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_.lParam) / scale); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_PointerId(uint32_t* pointer_id) override { - // TODO(ananta) - // Implement this properly. - *pointer_id = 1; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_Timestamp(uint64_t* timestamp) override { - *timestamp = msg_.time; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_Properties(winui::Input::IPointerPointProperties** properties) override { - return QueryInterface(winui::Input::IID_IPointerPointProperties, - reinterpret_cast<void**>(properties)); - } - - HRESULT STDMETHODCALLTYPE - get_RawPosition(winfoundtn::Point* position) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_FrameId(uint32_t* frame_id) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsInContact(boolean* in_contact) override { - return E_NOTIMPL; - } - - // IPointerPointProperties implementation. - HRESULT STDMETHODCALLTYPE - get_PointerUpdateKind(winui::Input::PointerUpdateKind* update_kind) override { - // TODO(ananta) - // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into - // equivalents. - if (msg_.message == WM_LBUTTONDOWN) { - *update_kind = winui::Input::PointerUpdateKind_LeftButtonPressed; - } else if (msg_.message == WM_RBUTTONDOWN) { - *update_kind = winui::Input::PointerUpdateKind_RightButtonPressed; - } else if (msg_.message == WM_MBUTTONDOWN) { - *update_kind = winui::Input::PointerUpdateKind_MiddleButtonPressed; - } else if (msg_.message == WM_LBUTTONUP) { - *update_kind = winui::Input::PointerUpdateKind_LeftButtonReleased; - } else if (msg_.message == WM_RBUTTONUP) { - *update_kind = winui::Input::PointerUpdateKind_RightButtonReleased; - } else if (msg_.message == WM_MBUTTONUP) { - *update_kind = winui::Input::PointerUpdateKind_MiddleButtonReleased; - } - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_IsLeftButtonPressed(boolean* left_button_pressed) override { - *left_button_pressed = msg_.wParam & MK_LBUTTON ? true : false; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_IsRightButtonPressed(boolean* right_button_pressed) override { - *right_button_pressed = msg_.wParam & MK_RBUTTON ? true : false; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_IsMiddleButtonPressed(boolean* middle_button_pressed) override { - *middle_button_pressed = msg_.wParam & MK_MBUTTON ? true : false; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_IsHorizontalMouseWheel(boolean* is_horizontal_mouse_wheel) override { - *is_horizontal_mouse_wheel = - (msg_.message == WM_MOUSEHWHEEL) ? true : false; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_MouseWheelDelta(int* delta) override { - if (msg_.message == WM_MOUSEWHEEL || msg_.message == WM_MOUSEHWHEEL) { - *delta = GET_WHEEL_DELTA_WPARAM(msg_.wParam); - return S_OK; - } else { - return S_FALSE; - } - } - - HRESULT STDMETHODCALLTYPE get_Pressure(float* pressure) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsInverted(boolean* inverted) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsEraser(boolean* is_eraser) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_Orientation(float* orientation) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_XTilt(float* x_tilt) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_YTilt(float* y_tilt) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_Twist(float* twist) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_ContactRect(winfoundtn::Rect* rect) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE - get_ContactRectRaw(winfoundtn::Rect* rect) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_TouchConfidence(boolean* confidence) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsPrimary(boolean* is_primary) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsInRange(boolean* is_in_range) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_IsCanceled(boolean* is_canceled) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE - get_IsBarrelButtonPressed(boolean* is_barrel_button_pressed) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE - get_IsXButton1Pressed(boolean* is_xbutton1_pressed) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE - get_IsXButton2Pressed(boolean* is_xbutton2_pressed) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE HasUsage(uint32_t usage_page, - uint32_t usage_id, - boolean* has_usage) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE GetUsageValue(uint32_t usage_page, - uint32_t usage_id, - int32_t* usage_value) override { - return E_NOTIMPL; - } - - // IPointerDevice implementation. - HRESULT STDMETHODCALLTYPE get_PointerDeviceType( - windevs::Input::PointerDeviceType* device_type) override { - if (msg_.message == WM_TOUCH) { - *device_type = windevs::Input::PointerDeviceType_Touch; - } else { - *device_type = windevs::Input::PointerDeviceType_Mouse; - } - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_IsIntegrated(boolean* is_integrated) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_MaxContacts(uint32_t* contacts) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE - get_PhysicalDeviceRect(winfoundtn::Rect* rect) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_ScreenRect(winfoundtn::Rect* rect) override { - return E_NOTIMPL; - } - - HRESULT STDMETHODCALLTYPE get_SupportedUsages( - winfoundtn::Collections::IVectorView<windevs::Input::PointerDeviceUsage>** - usages) override { - return E_NOTIMPL; - } - - private: - MSG msg_; - - DISALLOW_COPY_AND_ASSIGN(MouseEvent); -}; - -// This class implements the winrt interfaces needed to support keyboard -// character and system character messages. -class KeyEvent : public mswr::RuntimeClass< - winui::Core::IKeyEventArgs, - winui::Core::ICharacterReceivedEventArgs, - winui::Core::IAcceleratorKeyEventArgs> { - public: - KeyEvent(const MSG& msg) - : msg_(msg) {} - - // IKeyEventArgs implementation. - HRESULT STDMETHODCALLTYPE - get_VirtualKey(winsys::VirtualKey* virtual_key) override { - *virtual_key = static_cast<winsys::VirtualKey>(msg_.wParam); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_KeyStatus(winui::Core::CorePhysicalKeyStatus* key_status) override { - // As per msdn documentation for the keyboard messages. - key_status->RepeatCount = msg_.lParam & 0x0000FFFF; - key_status->ScanCode = (msg_.lParam >> 16) & 0x00FF; - key_status->IsExtendedKey = (msg_.lParam & (1 << 24)); - key_status->IsMenuKeyDown = (msg_.lParam & (1 << 29)); - key_status->WasKeyDown = (msg_.lParam & (1 << 30)); - key_status->IsKeyReleased = (msg_.lParam & (1 << 31)); - return S_OK; - } - - // ICharacterReceivedEventArgs implementation. - HRESULT STDMETHODCALLTYPE get_KeyCode(uint32_t* key_code) override { - *key_code = msg_.wParam; - return S_OK; - } - - // IAcceleratorKeyEventArgs implementation. - HRESULT STDMETHODCALLTYPE - get_EventType(winui::Core::CoreAcceleratorKeyEventType* event_type) override { - if (msg_.message == WM_SYSKEYDOWN) { - *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown; - } else if (msg_.message == WM_SYSKEYUP) { - *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp; - } else if (msg_.message == WM_SYSCHAR) { - *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemCharacter; - } - return S_OK; - } - - private: - MSG msg_; -}; - -// 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 CoreDispatcherEmulation : - public mswr::RuntimeClass< - winui::Core::ICoreDispatcher, - winui::Core::ICoreAcceleratorKeys> { - public: - CoreDispatcherEmulation(InputHandler* input_handler) - : input_handler_(input_handler), - accelerator_key_event_handler_(NULL) {} - - // ICoreDispatcher implementation: - HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - ProcessEvents(winui::Core::CoreProcessEventsOption options) override { - // 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) && g_window_count > 0) { - ProcessInputMessage(msg); - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - // TODO(cpu): figure what to do with msg.WParam which we would normally - // return here. - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - RunAsync(winui::Core::CoreDispatcherPriority priority, - winui::Core::IDispatchedHandler* agileCallback, - ABI::Windows::Foundation::IAsyncAction** asyncAction) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - RunIdleAsync(winui::Core::IIdleDispatchedHandler* agileCallback, - winfoundtn::IAsyncAction** asyncAction) override { - return S_OK; - } - - // ICoreAcceleratorKeys implementation: - HRESULT STDMETHODCALLTYPE - add_AcceleratorKeyActivated(AcceleratorKeyEventHandler* handler, - EventRegistrationToken* pCookie) override { - accelerator_key_event_handler_ = handler; - accelerator_key_event_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - remove_AcceleratorKeyActivated(EventRegistrationToken cookie) override { - accelerator_key_event_handler_->Release(); - accelerator_key_event_handler_ = NULL; - return S_OK; - } - - private: - bool ProcessInputMessage(const MSG& msg) { - // Poor man's way of dispatching input events. - bool ret = false; - if (input_handler_) { - if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) { - if ((msg.message == WM_SYSKEYDOWN) || (msg.message == WM_SYSKEYUP) || - msg.message == WM_SYSCHAR) { - ret = HandleSystemKeys(msg); - } else { - ret = input_handler_->HandleKeyboardMessage(msg); - } - } else if ((msg.message >= WM_MOUSEFIRST) && - (msg.message <= WM_MOUSELAST)) { - ret = input_handler_->HandleMouseMessage(msg); - } - } - return ret; - } - - bool HandleSystemKeys(const MSG& msg) { - mswr::ComPtr<winui::Core::IAcceleratorKeyEventArgs> event_args; - event_args = mswr::Make<KeyEvent>(msg); - accelerator_key_event_handler_->Invoke(this, event_args.Get()); - return true; - } - - InputHandler* input_handler_; - AcceleratorKeyEventHandler* accelerator_key_event_handler_; -}; - -class CoreWindowEmulation - : public mswr::RuntimeClass< - mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>, - winui::Core::ICoreWindow, ICoreWindowInterop>, - public InputHandler { - public: - CoreWindowEmulation(winapp::Core::IFrameworkView* app_view) - : mouse_moved_handler_(NULL), - mouse_capture_lost_handler_(NULL), - mouse_pressed_handler_(NULL), - mouse_released_handler_(NULL), - mouse_entered_handler_(NULL), - mouse_exited_handler_(NULL), - mouse_wheel_changed_handler_(NULL), - key_down_handler_(NULL), - key_up_handler_(NULL), - character_received_handler_(NULL), - core_hwnd_(NULL), - app_view_(app_view), - window_activated_handler_(NULL) { - dispatcher_ = mswr::Make<CoreDispatcherEmulation>(this); - - // Unless we select our own AppUserModelID the shell might confuse us - // with the app launcher one and we get the wrong taskbar button and icon. - ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId); - - RECT work_area = {0}; - ::SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0); - if (::IsDebuggerPresent()) { - work_area.top = 0; - work_area.left = 0; - work_area.right = 1600; - work_area.bottom = 900; - } - - core_hwnd_ = CreateMetroTopLevelWindow(work_area); - ::SetProp(core_hwnd_, kAshWin7CoreWindowHandler, this); - } - - ~CoreWindowEmulation() override { - if (core_hwnd_) { - ::RemoveProp(core_hwnd_, kAshWin7CoreWindowHandler); - ::DestroyWindow(core_hwnd_); - } - } - - // ICoreWindow implementation: - HRESULT STDMETHODCALLTYPE - get_AutomationHostProvider(IInspectable** value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_Bounds(winfoundtn::Rect* value) override { - RECT rect; - if (!::GetClientRect(core_hwnd_, &rect)) - return E_FAIL; - value->Width = rect.right; - value->Height = rect.bottom; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_CustomProperties(winfoundtn::Collections::IPropertySet** value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_Dispatcher(winui::Core::ICoreDispatcher** value) override { - return dispatcher_.CopyTo(value); - } - - HRESULT STDMETHODCALLTYPE - get_FlowDirection(winui::Core::CoreWindowFlowDirection* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - put_FlowDirection(winui::Core::CoreWindowFlowDirection value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_IsInputEnabled(boolean* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE put_IsInputEnabled(boolean value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_PointerCursor(winui::Core::ICoreCursor** value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - put_PointerCursor(winui::Core::ICoreCursor* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_PointerPosition(winfoundtn::Point* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_Visible(boolean* value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Activate(void) override { - // After we fire OnActivate on the View, Chrome calls us back here. - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Close(void) override { - ::PostMessage(core_hwnd_, WM_CLOSE, 0, 0); - core_hwnd_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetAsyncKeyState( - ABI::Windows::System::VirtualKey virtualKey, - winui::Core::CoreVirtualKeyStates* KeyState) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetKeyState( - ABI::Windows::System::VirtualKey virtualKey, - winui::Core::CoreVirtualKeyStates* KeyState) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE SetPointerCapture(void) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_Activated( - WindowActivatedHandler* handler, - EventRegistrationToken* pCookie) override { - window_activated_handler_ = handler; - handler->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_Activated( - EventRegistrationToken cookie) override { - window_activated_handler_->Release(); - window_activated_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested( - AutomationProviderHandler* handler, - EventRegistrationToken* cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested( - EventRegistrationToken cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_CharacterReceived( - CharEventHandler* handler, - EventRegistrationToken* pCookie) override { - character_received_handler_ = handler; - character_received_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_CharacterReceived( - EventRegistrationToken cookie) override { - character_received_handler_->Release(); - character_received_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_Closed( - CoreWindowEventHandler* handler, - EventRegistrationToken* pCookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_Closed( - EventRegistrationToken cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_InputEnabled( - InputEnabledEventHandler* handler, - EventRegistrationToken* pCookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_InputEnabled( - EventRegistrationToken cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_KeyDown( - KeyEventHandler* handler, - EventRegistrationToken* pCookie) override { - key_down_handler_ = handler; - key_down_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_KeyDown( - EventRegistrationToken cookie) override { - key_down_handler_->Release(); - key_down_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_KeyUp( - KeyEventHandler* handler, - EventRegistrationToken* pCookie) override { - key_up_handler_ = handler; - key_up_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_KeyUp( - EventRegistrationToken cookie) override { - key_up_handler_->Release(); - key_up_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerCaptureLost( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_capture_lost_handler_ = handler; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost( - EventRegistrationToken cookie) override { - mouse_capture_lost_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerEntered( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_entered_handler_ = handler; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerEntered( - EventRegistrationToken cookie) override { - mouse_entered_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerExited( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_exited_handler_ = handler; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerExited( - EventRegistrationToken cookie) override { - mouse_exited_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerMoved( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_moved_handler_ = handler; - mouse_moved_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerMoved( - EventRegistrationToken cookie) override { - mouse_moved_handler_->Release(); - mouse_moved_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerPressed( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_pressed_handler_ = handler; - mouse_pressed_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerPressed( - EventRegistrationToken cookie) override { - mouse_pressed_handler_->Release(); - mouse_pressed_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerReleased( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_released_handler_ = handler; - mouse_released_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerReleased( - EventRegistrationToken cookie) override { - mouse_released_handler_->Release(); - mouse_released_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_TouchHitTesting( - TouchHitTestHandler* handler, - EventRegistrationToken* pCookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_TouchHitTesting( - EventRegistrationToken cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_PointerWheelChanged( - PointerEventHandler* handler, - EventRegistrationToken* cookie) override { - mouse_wheel_changed_handler_ = handler; - mouse_wheel_changed_handler_->AddRef(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged( - EventRegistrationToken cookie) override { - mouse_wheel_changed_handler_->Release(); - mouse_wheel_changed_handler_ = NULL; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_SizeChanged( - SizeChangedHandler* handler, - EventRegistrationToken* pCookie) override { - // TODO(cpu): implement this. - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_SizeChanged( - EventRegistrationToken cookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE add_VisibilityChanged( - VisibilityChangedHandler* handler, - EventRegistrationToken* pCookie) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( - EventRegistrationToken cookie) override { - return S_OK; - } - - // ICoreWindowInterop implementation: - HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) override { - if (!core_hwnd_) - return E_FAIL; - *hwnd = core_hwnd_; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE put_MessageHandled(boolean value) override { - return S_OK; - } - - // InputHandler - bool HandleKeyboardMessage(const MSG& msg) override { - switch (msg.message) { - case WM_KEYDOWN: - case WM_KEYUP: { - mswr::ComPtr<winui::Core::IKeyEventArgs> event_args; - event_args = mswr::Make<KeyEvent>(msg); - KeyEventHandler* handler = NULL; - if (msg.message == WM_KEYDOWN) { - handler = key_down_handler_; - } else { - handler = key_up_handler_; - } - handler->Invoke(this, event_args.Get()); - break; - } - - case WM_CHAR: - case WM_DEADCHAR: - case WM_UNICHAR: { - mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> event_args; - event_args = mswr::Make<KeyEvent>(msg); - character_received_handler_->Invoke(this, event_args.Get()); - break; - } - - default: - return false; - } - return true; - } - - bool HandleMouseMessage(const MSG& msg) override { - PointerEventHandler* handler = NULL; - mswr::ComPtr<winui::Core::IPointerEventArgs> event_args; - event_args = mswr::Make<MouseEvent>(msg); - switch (msg.message) { - case WM_MOUSEMOVE: { - handler = mouse_moved_handler_; - break; - } - case WM_LBUTTONDOWN: { - case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: - handler = mouse_pressed_handler_; - break; - } - - case WM_LBUTTONUP: { - case WM_RBUTTONUP: - case WM_MBUTTONUP: - handler = mouse_released_handler_; - break; - } - - case WM_MOUSEWHEEL: { - case WM_MOUSEHWHEEL: - handler = mouse_wheel_changed_handler_; - break; - } - - default: - return false; - } - DCHECK(handler); - handler->Invoke(this, event_args.Get()); - return true; - } - - void OnWindowActivated() { - if (window_activated_handler_) - window_activated_handler_->Invoke(this, NULL); - } - - private: - PointerEventHandler* mouse_moved_handler_; - PointerEventHandler* mouse_capture_lost_handler_; - PointerEventHandler* mouse_pressed_handler_; - PointerEventHandler* mouse_released_handler_; - PointerEventHandler* mouse_entered_handler_; - PointerEventHandler* mouse_exited_handler_; - PointerEventHandler* mouse_wheel_changed_handler_; - KeyEventHandler* key_down_handler_; - KeyEventHandler* key_up_handler_; - CharEventHandler* character_received_handler_; - HWND core_hwnd_; - mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher_; - mswr::ComPtr<winapp::Core::IFrameworkView> app_view_; - WindowActivatedHandler* window_activated_handler_; -}; - -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) { - PAINTSTRUCT ps; - HDC hdc; - switch (message) { - case WM_ACTIVATE: { - // HIWORD(wparam) is 1 if the window is minimized. - bool active = (LOWORD(wparam) != WA_INACTIVE) && !HIWORD(wparam); - if (active) { - CoreWindowEmulation* core_window_handler = - reinterpret_cast<CoreWindowEmulation*>( - ::GetProp(hwnd, kAshWin7CoreWindowHandler)); - if (core_window_handler) - core_window_handler->OnWindowActivated(); - } - return ::DefWindowProc(hwnd, message, wparam, lparam); - } - case WM_CREATE: - ++g_window_count; - break; - case WM_PAINT: - hdc = ::BeginPaint(hwnd, &ps); - ::EndPaint(hwnd, &ps); - break; - case WM_CLOSE: - ::DestroyWindow(hwnd); - break; - case WM_DESTROY: - --g_window_count; - if (!g_window_count) - ::PostQuitMessage(0); - break; - // Always allow Chrome to set the cursor. - case WM_SETCURSOR: - return 1; - default: - return ::DefWindowProc(hwnd, message, wparam, lparam); - } - return 0; -} - -class ActivatedEvent - : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> { - public: - ActivatedEvent(winapp::Activation::ActivationKind activation_kind) - : activation_kind_(activation_kind) { - } - - HRESULT STDMETHODCALLTYPE - get_Kind(winapp::Activation::ActivationKind* value) override { - *value = activation_kind_; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_PreviousExecutionState( - winapp::Activation::ApplicationExecutionState* value) override { - *value = winapp::Activation::ApplicationExecutionState_ClosedByUser; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_SplashScreen(winapp::Activation::ISplashScreen** value) override { - return E_FAIL; - } - - private: - winapp::Activation::ActivationKind activation_kind_; -}; - -class CoreApplicationViewEmulation - : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> { - public: - CoreApplicationViewEmulation(winapp::Core::IFrameworkView* app_view) { - core_window_ = mswr::Make<CoreWindowEmulation>(app_view); - } - - 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; - } - } - - HRESULT Close() { - return core_window_->Close(); - } - - // ICoreApplicationView implementation: - HRESULT STDMETHODCALLTYPE - get_CoreWindow(winui::Core::ICoreWindow** value) override { - if (!core_window_) - return E_FAIL; - return core_window_.CopyTo(value); - } - - HRESULT STDMETHODCALLTYPE - add_Activated(ActivatedHandler* handler, - EventRegistrationToken* token) override { - // The real component supports multiple handles but we don't yet. - if (activated_handler_) - return E_FAIL; - activated_handler_ = handler; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - remove_Activated(EventRegistrationToken token) override { - // Chrome never unregisters handlers, so we don't care about it. - return S_OK; - } - - HRESULT STDMETHODCALLTYPE get_IsMain(boolean* value) override { return S_OK; } - - HRESULT STDMETHODCALLTYPE get_IsHosted(boolean* value) override { - return S_OK; - } - - private: - mswr::ComPtr<CoreWindowEmulation> core_window_; - mswr::ComPtr<ActivatedHandler> activated_handler_; -}; - -class CoreApplicationWin7Emulation - : public mswr::RuntimeClass<winapp::Core::ICoreApplication, - winapp::Core::ICoreApplicationExit> { - public: - // ICoreApplication implementation: - - HRESULT STDMETHODCALLTYPE get_Id(HSTRING* value) override { return S_OK; } - - HRESULT STDMETHODCALLTYPE add_Suspending( - winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler, - EventRegistrationToken* token) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - remove_Suspending(EventRegistrationToken token) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - add_Resuming(winfoundtn::IEventHandler<IInspectable*>* handler, - EventRegistrationToken* token) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - remove_Resuming(EventRegistrationToken token) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - get_Properties(winfoundtn::Collections::IPropertySet** value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - GetCurrentView(winapp::Core::ICoreApplicationView** value) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - Run(winapp::Core::IFrameworkViewSource* viewSource) override { - HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf()); - if (FAILED(hr)) - return hr; - view_emulation_ = mswr::Make<CoreApplicationViewEmulation>( - app_view_.Get()); - 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(); - } - - HRESULT STDMETHODCALLTYPE RunWithActivationFactories( - winfoundtn::IGetActivationFactory* activationFactoryCallback) override { - return S_OK; - } - - // ICoreApplicationExit implementation: - - HRESULT STDMETHODCALLTYPE Exit(void) override { - return view_emulation_->Close(); - } - - HRESULT STDMETHODCALLTYPE - add_Exiting(winfoundtn::IEventHandler<IInspectable*>* handler, - EventRegistrationToken* token) override { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - remove_Exiting(EventRegistrationToken token) override { - return S_OK; - } - - private: - mswr::ComPtr<winapp::Core::IFrameworkView> app_view_; - mswr::ComPtr<CoreApplicationViewEmulation> view_emulation_; -}; - - -mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7() { - HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (FAILED(hr)) - CHECK(false); - return mswr::Make<CoreApplicationWin7Emulation>(); -} - diff --git a/win8/viewer/metro_viewer_constants.cc b/win8/viewer/metro_viewer_constants.cc deleted file mode 100644 index fd54fe4..0000000 --- a/win8/viewer/metro_viewer_constants.cc +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 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_constants.h" - -namespace win8 { - -const char kMetroViewerIPCChannelName[] = "viewer"; - -const wchar_t kMetroViewerConnectVerb[] = L"connect"; - -} // namespace win8 diff --git a/win8/viewer/metro_viewer_constants.h b/win8/viewer/metro_viewer_constants.h deleted file mode 100644 index 560a450..0000000 --- a/win8/viewer/metro_viewer_constants.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 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_CONSTANTS_H_ -#define WIN8_VIEWER_METRO_VIEWER_CONSTANTS_H_ - -namespace win8 { - -// The name of the IPC channel between the browser process and the metro viewer -// process. -extern const char kMetroViewerIPCChannelName[]; - -// Tells the viewer process to simply connect back without needing to launch a -// browser process itself. -extern const wchar_t kMetroViewerConnectVerb[]; - -} // namespace win8 - -#endif // WIN8_VIEWER_METRO_VIEWER_CONSTANTS_H_ diff --git a/win8/viewer/metro_viewer_exports.h b/win8/viewer/metro_viewer_exports.h deleted file mode 100644 index 61ff7d5..0000000 --- a/win8/viewer/metro_viewer_exports.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2014 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 METRO_VIEWER_METRO_VIEWER_H_ -#define METRO_VIEWER_METRO_VIEWER_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(METRO_VIEWER_IMPLEMENTATION) -#define METRO_VIEWER_EXPORT __declspec(dllexport) -#else -#define METRO_VIEWER_EXPORT __declspec(dllimport) -#endif // defined(METRO_VIEWER_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(METRO_VIEWER_IMPLEMENTATION) -#define METRO_VIEWER_EXPORT __attribute__((visibility("default"))) -#else -#define METRO_VIEWER_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define METRO_VIEWER_EXPORT -#endif - -#endif // METRO_VIEWER_METRO_VIEWER_H_ diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc deleted file mode 100644 index a365241..0000000 --- a/win8/viewer/metro_viewer_process_host.cc +++ /dev/null @@ -1,346 +0,0 @@ -// 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 <stdint.h> - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/memory/ref_counted.h" -#include "base/path_service.h" -#include "base/process/process.h" -#include "base/strings/string16.h" -#include "base/synchronization/waitable_event.h" -#include "base/time/time.h" -#include "base/win/scoped_comptr.h" -#include "base/win/windows_version.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_message.h" -#include "ipc/ipc_message_macros.h" -#include "ui/aura/remote_window_tree_host_win.h" -#include "ui/metro_viewer/metro_viewer_messages.h" -#include "win8/viewer/metro_viewer_constants.h" - -namespace { - -const int kViewerProcessConnectionTimeoutSecs = 60; - -} // namespace - -namespace win8 { - -// static -MetroViewerProcessHost* MetroViewerProcessHost::instance_ = NULL; - -MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter( - MetroViewerProcessHost* owner) - : owner_(owner) { -} - -void MetroViewerProcessHost::InternalMessageFilter::OnChannelConnected( - int32_t peer_pid) { - owner_->NotifyChannelConnected(); -} - -MetroViewerProcessHost::InternalMessageFilter::~InternalMessageFilter() { -} - -MetroViewerProcessHost::MetroViewerProcessHost( - const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { - DCHECK(!instance_); - instance_ = this; - - channel_ = IPC::ChannelProxy::Create(kMetroViewerIPCChannelName, - IPC::Channel::MODE_NAMED_SERVER, - this, - ipc_task_runner); -} - -MetroViewerProcessHost::~MetroViewerProcessHost() { - if (!channel_) { - instance_ = NULL; - return; - } - - base::ProcessId viewer_process_id = GetViewerProcessId(); - channel_->Close(); - if (message_filter_.get()) { - // Wait for the viewer process to go away. - if (viewer_process_id != base::kNullProcessId) { - base::Process viewer_process = - base::Process::OpenWithAccess( - viewer_process_id, - PROCESS_QUERY_INFORMATION | SYNCHRONIZE); - if (viewer_process.IsValid()) { - int exit_code; - viewer_process.WaitForExit(&exit_code); - } - } - channel_->RemoveFilter(message_filter_.get()); - } - instance_ = NULL; -} - -base::ProcessId MetroViewerProcessHost::GetViewerProcessId() { - if (channel_) - return channel_->GetPeerPID(); - return base::kNullProcessId; -} - -bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection( - const base::string16& app_user_model_id) { - DCHECK_EQ(base::kNullProcessId, channel_->GetPeerPID()); - - channel_connected_event_.reset(new base::WaitableEvent(false, false)); - - message_filter_ = new InternalMessageFilter(this); - channel_->AddFilter(message_filter_.get()); - - if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - base::win::ScopedComPtr<IApplicationActivationManager> activator; - HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); - if (SUCCEEDED(hr)) { - DWORD pid = 0; - // Use the "connect" verb to - hr = activator->ActivateApplication( - app_user_model_id.c_str(), kMetroViewerConnectVerb, AO_NONE, &pid); - } - - LOG_IF(ERROR, FAILED(hr)) << "Tried and failed to launch Metro Chrome. " - << "hr=" << std::hex << hr; - } else { - // For Windows 7 we need to launch the viewer ourselves. - base::FilePath chrome_path; - if (!PathService::Get(base::DIR_EXE, &chrome_path)) - return false; - // TODO(cpu): launch with "-ServerName:DefaultBrowserServer" - // note that the viewer might try to launch chrome again. - CHECK(false); - } - - // Having launched the viewer process, now we wait for it to connect. - bool success = - channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds( - kViewerProcessConnectionTimeoutSecs)); - channel_connected_event_.reset(); - 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_FileSaveAsDone, - OnFileSaveAsDone) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_FileOpenDone, - OnFileOpenDone) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MultiFileOpenDone, - OnMultiFileOpenDone) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_OpenURL, OnOpenURL) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SearchRequest, OnHandleSearchRequest) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SelectFolderDone, - OnSelectFolderDone) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetTargetSurface, OnSetTargetSurface) - IPC_MESSAGE_HANDLER(MetroViewerHostMsg_WindowSizeChanged, - OnWindowSizeChanged) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled ? true : - aura::RemoteWindowTreeHostWin::Instance()->OnMessageReceived(message); -} - -// static -void MetroViewerProcessHost::HandleActivateDesktop( - const base::FilePath& path, - bool ash_exit) { - if (instance_) { - instance_->Send( - new MetroViewerHostMsg_ActivateDesktop(path, ash_exit)); - } -} - -// static -void MetroViewerProcessHost::HandleMetroExit() { - if (instance_) - instance_->Send(new MetroViewerHostMsg_MetroExit()); -} - -// static -void MetroViewerProcessHost::HandleOpenFile( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenFileCompletion& on_success, - const FileSelectionCanceled& on_failure) { - if (instance_) { - instance_->HandleOpenFileImpl(title, default_path, filter, on_success, - on_failure); - } -} - -// static -void MetroViewerProcessHost::HandleOpenMultipleFiles( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenMultipleFilesCompletion& on_success, - const FileSelectionCanceled& on_failure) { - if (instance_) { - instance_->HandleOpenMultipleFilesImpl(title, default_path, filter, - on_success, on_failure); - } -} - -// static -void MetroViewerProcessHost::HandleSaveFile( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - int filter_index, - const base::string16& default_extension, - const SaveFileCompletion& on_success, - const FileSelectionCanceled& on_failure) { - if (instance_) { - instance_->HandleSaveFileImpl(title, default_path, filter, filter_index, - default_extension, on_success, on_failure); - } -} - -// static -void MetroViewerProcessHost::HandleSelectFolder( - const base::string16& title, - const SelectFolderCompletion& on_success, - const FileSelectionCanceled& on_failure) { - if (instance_) - instance_->HandleSelectFolderImpl(title, on_success, on_failure); -} - -void MetroViewerProcessHost::HandleOpenFileImpl( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenFileCompletion& on_success, - const FileSelectionCanceled& on_failure) { - // Can only have one of these operations in flight. - DCHECK(file_open_completion_callback_.is_null()); - DCHECK(failure_callback_.is_null()); - - file_open_completion_callback_ = on_success; - failure_callback_ = on_failure; - - Send(new MetroViewerHostMsg_DisplayFileOpen(title, filter, default_path, - false)); -} - -void MetroViewerProcessHost::HandleOpenMultipleFilesImpl( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenMultipleFilesCompletion& on_success, - const FileSelectionCanceled& on_failure) { - // Can only have one of these operations in flight. - DCHECK(multi_file_open_completion_callback_.is_null()); - DCHECK(failure_callback_.is_null()); - multi_file_open_completion_callback_ = on_success; - failure_callback_ = on_failure; - - Send(new MetroViewerHostMsg_DisplayFileOpen(title, filter, default_path, - true)); -} - -void MetroViewerProcessHost::HandleSaveFileImpl( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - int filter_index, - const base::string16& default_extension, - const SaveFileCompletion& on_success, - const FileSelectionCanceled& on_failure) { - MetroViewerHostMsg_SaveAsDialogParams params; - params.title = title; - params.default_extension = default_extension; - params.filter = filter; - params.filter_index = filter_index; - params.suggested_name = default_path; - - // Can only have one of these operations in flight. - DCHECK(file_saveas_completion_callback_.is_null()); - DCHECK(failure_callback_.is_null()); - file_saveas_completion_callback_ = on_success; - failure_callback_ = on_failure; - - Send(new MetroViewerHostMsg_DisplayFileSaveAs(params)); -} - -void MetroViewerProcessHost::HandleSelectFolderImpl( - const base::string16& title, - const SelectFolderCompletion& on_success, - const FileSelectionCanceled& on_failure) { - // Can only have one of these operations in flight. - DCHECK(select_folder_completion_callback_.is_null()); - DCHECK(failure_callback_.is_null()); - select_folder_completion_callback_ = on_success; - failure_callback_ = on_failure; - - Send(new MetroViewerHostMsg_DisplaySelectFolder(title)); -} - -void MetroViewerProcessHost::NotifyChannelConnected() { - if (channel_connected_event_) - channel_connected_event_->Signal(); -} - -void MetroViewerProcessHost::OnFileSaveAsDone(bool success, - const base::FilePath& filename, - int filter_index) { - if (success) - file_saveas_completion_callback_.Run(filename, filter_index, NULL); - else - failure_callback_.Run(NULL); - file_saveas_completion_callback_.Reset(); - failure_callback_.Reset(); -} - - -void MetroViewerProcessHost::OnFileOpenDone(bool success, - const base::FilePath& filename) { - if (success) - file_open_completion_callback_.Run(base::FilePath(filename), 0, NULL); - else - failure_callback_.Run(NULL); - file_open_completion_callback_.Reset(); - failure_callback_.Reset(); -} - -void MetroViewerProcessHost::OnMultiFileOpenDone( - bool success, - const std::vector<base::FilePath>& files) { - if (success) - multi_file_open_completion_callback_.Run(files, NULL); - else - failure_callback_.Run(NULL); - multi_file_open_completion_callback_.Reset(); - failure_callback_.Reset(); -} - -void MetroViewerProcessHost::OnSelectFolderDone( - bool success, - const base::FilePath& folder) { - if (success) - select_folder_completion_callback_.Run(base::FilePath(folder), 0, NULL); - else - failure_callback_.Run(NULL); - select_folder_completion_callback_.Reset(); - failure_callback_.Reset(); -} - -} // namespace win8 diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h deleted file mode 100644 index 2b1a56f..0000000 --- a/win8/viewer/metro_viewer_process_host.h +++ /dev/null @@ -1,221 +0,0 @@ -// 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 <stdint.h> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/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 "ipc/message_filter.h" -#include "ui/gfx/native_widget_types.h" -#include "win8/viewer/metro_viewer_exports.h" - -namespace base { -class SingleThreadTaskRunner; -class WaitableEvent; -} - -namespace IPC { -class ChannelProxy; -class Message; -} - -namespace win8 { - -// Abstract base class for various Metro viewer process host implementations. -class METRO_VIEWER_EXPORT MetroViewerProcessHost : public IPC::Listener, - public IPC::Sender, - public base::NonThreadSafe { - public: - typedef base::Callback<void(const base::FilePath&, int, void*)> - OpenFileCompletion; - - typedef base::Callback<void(const std::vector<base::FilePath>&, void*)> - OpenMultipleFilesCompletion; - - typedef base::Callback<void(const base::FilePath&, int, void*)> - SaveFileCompletion; - - typedef base::Callback<void(const base::FilePath&, int, void*)> - SelectFolderCompletion; - - typedef base::Callback<void(void*)> FileSelectionCanceled; - - // Initializes a viewer process host to connect to the Metro viewer process - // over IPC. 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(). - explicit MetroViewerProcessHost( - const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner); - ~MetroViewerProcessHost() override; - - // 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); - - // Handles the activate desktop command for Metro Chrome Ash. The |ash_exit| - // parameter indicates whether the Ash process would be shutdown after - // activating the desktop. - static void HandleActivateDesktop(const base::FilePath& shortcut, - bool ash_exit); - - // Handles the metro exit command. Notifies the metro viewer to shutdown - // gracefully. - static void HandleMetroExit(); - - // Handles the open file operation for Metro Chrome Ash. The on_success - // callback passed in is invoked when we receive the opened file name from - // the metro viewer. The on failure callback is invoked on failure. - static void HandleOpenFile(const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenFileCompletion& on_success, - const FileSelectionCanceled& on_failure); - - // Handles the open multiple file operation for Metro Chrome Ash. The - // on_success callback passed in is invoked when we receive the opened file - // names from the metro viewer. The on failure callback is invoked on failure. - static void HandleOpenMultipleFiles( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenMultipleFilesCompletion& on_success, - const FileSelectionCanceled& on_failure); - - // Handles the save file operation for Metro Chrome Ash. The on_success - // callback passed in is invoked when we receive the saved file name from - // the metro viewer. The on failure callback is invoked on failure. - static void HandleSaveFile(const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - int filter_index, - const base::string16& default_extension, - const SaveFileCompletion& on_success, - const FileSelectionCanceled& on_failure); - - // Handles the select folder for Metro Chrome Ash. The on_success - // callback passed in is invoked when we receive the folder name from the - // metro viewer. The on failure callback is invoked on failure. - static void HandleSelectFolder(const base::string16& title, - const SelectFolderCompletion& on_success, - const FileSelectionCanceled& on_failure); - - protected: - // IPC::Sender implementation: - bool Send(IPC::Message* msg) override; - - // IPC::Listener implementation: - bool OnMessageReceived(const IPC::Message& message) override; - void OnChannelError() override = 0; - - private: - // The following are the implementation for the corresponding static methods - // above, see them for descriptions. - void HandleOpenFileImpl(const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenFileCompletion& on_success, - const FileSelectionCanceled& on_failure); - void HandleOpenMultipleFilesImpl( - const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - const OpenMultipleFilesCompletion& on_success, - const FileSelectionCanceled& on_failure); - void HandleSaveFileImpl(const base::string16& title, - const base::FilePath& default_path, - const base::string16& filter, - int filter_index, - const base::string16& default_extension, - const SaveFileCompletion& on_success, - const FileSelectionCanceled& on_failure); - void HandleSelectFolderImpl(const base::string16& title, - const SelectFolderCompletion& on_success, - const FileSelectionCanceled& on_failure); - - // 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, - float device_scale) = 0; - - // Called over IPC by the viewer process to request that the url passed in be - // opened. - virtual void OnOpenURL(const base::string16& url) = 0; - - // Called over IPC by the viewer process to request that the search string - // passed in is passed to the default search provider and a URL navigation be - // performed. - virtual void OnHandleSearchRequest(const base::string16& search_string) = 0; - - // Called over IPC by the viewer process when the window size has changed. - virtual void OnWindowSizeChanged(uint32_t width, uint32_t height) = 0; - - void NotifyChannelConnected(); - - // IPC message handing methods: - void OnFileSaveAsDone(bool success, - const base::FilePath& filename, - int filter_index); - void OnFileOpenDone(bool success, const base::FilePath& filename); - void OnMultiFileOpenDone(bool success, - const std::vector<base::FilePath>& files); - void OnSelectFolderDone(bool success, const base::FilePath& folder); - - // 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::MessageFilter { - public: - InternalMessageFilter(MetroViewerProcessHost* owner); - - // IPC::MessageFilter implementation. - void OnChannelConnected(int32_t peer_pid) override; - - private: - ~InternalMessageFilter() override; - - MetroViewerProcessHost* owner_; - DISALLOW_COPY_AND_ASSIGN(InternalMessageFilter); - }; - - scoped_ptr<IPC::ChannelProxy> channel_; - scoped_ptr<base::WaitableEvent> channel_connected_event_; - scoped_refptr<InternalMessageFilter> message_filter_; - - static MetroViewerProcessHost* instance_; - - // Saved callbacks which inform the caller about the result of the open file/ - // save file/select operations. - OpenFileCompletion file_open_completion_callback_; - OpenMultipleFilesCompletion multi_file_open_completion_callback_; - SaveFileCompletion file_saveas_completion_callback_; - SelectFolderCompletion select_folder_completion_callback_; - FileSelectionCanceled failure_callback_; - - 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 4c68624..8131fa3 100644 --- a/win8/win8.gyp +++ b/win8/win8.gyp @@ -10,35 +10,6 @@ ], 'targets': [ { - 'target_name': 'metro_viewer_constants', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'viewer/metro_viewer_constants.cc', - 'viewer/metro_viewer_constants.h', - ], - }, - { - 'target_name': 'metro_viewer', - 'type': '<(component)', - 'dependencies': [ - '../base/base.gyp:base', - '../ipc/ipc.gyp:ipc', - '../ui/aura/aura.gyp:aura', - '../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', - 'metro_viewer_constants' - ], - 'sources': [ - 'viewer/metro_viewer_process_host.cc', - 'viewer/metro_viewer_process_host.h', - ], - 'defines': [ - 'METRO_VIEWER_IMPLEMENTATION', - ], - }, - { 'target_name': 'test_support_win8', 'type': 'static_library', 'dependencies': [ |