| Index: win8/metro_driver/chrome_app_view_ash.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 01f9ba23441acf29317b8a110734e74ef6b40038..0000000000000000000000000000000000000000
 | 
| --- 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;
 | 
| -}
 | 
| 
 |