chrome_app_view_ash.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/stdafx.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/chrome_app_view_ash.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <corewindow.h>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <shellapi.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.foundation.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/process_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/metro.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sender.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/gestures/gesture_sequence.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/metro_viewer/metro_viewer_messages.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/metro_driver/file_picker_ash.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/metro_driver.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/winrt_utils.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "win8/viewer/metro_viewer_constants.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Core::CoreApplicationView*,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs*> ActivatedHandler;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::PointerEventArgs*> PointerEventHandler;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::KeyEventArgs*> KeyEventHandler;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::CoreDispatcher*,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CoreWindow*,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::CharacterReceivedEventArgs*> CharEventHandler;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::CoreWindow*,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::CoreWindow*,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)typedef winfoundtn::ITypedEventHandler<
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::CoreWindow*,
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler;
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function is exported by chrome.exe.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Global information used across the metro driver.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Globals {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winapp::Activation::ApplicationExecutionState previous_state;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winapp::Core::ICoreApplicationExit* app_exit;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BreakpadExceptionHandler breakpad_exception_handler;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} globals;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(robertshield): Share this with chrome_app_view.cc
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetroExit() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  globals.app_exit->Exit();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromeChannelListener : public IPC::Listener {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChromeChannelListener(base::MessageLoop* ui_loop, ChromeAppViewAsh* app_view)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : ui_proxy_(ui_loop->message_loop_proxy()), app_view_(app_view) {}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_BEGIN_MESSAGE_MAP(ChromeChannelListener, message)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursor, OnSetCursor)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileOpen,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          OnDisplayFileOpenDialog)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileSaveAs,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          OnDisplayFileSaveAsDialog)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplaySelectFolder,
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          OnDisplayFolderPicker)
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursorPos, OnSetCursorPos)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IPC_MESSAGE_UNHANDLED(__debugbreak())
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_END_MESSAGE_MAP()
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnChannelError() OVERRIDE {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Channel error";
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MetroExit();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnSetCursor(int64 cursor) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&ChromeAppViewAsh::OnSetCursor,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Unretained(app_view_),
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   reinterpret_cast<HCURSOR>(cursor)));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDisplayFileOpenDialog(const string16& title,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const string16& filter,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const base::FilePath& default_path,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               bool allow_multiple_files) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(FROM_HERE,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&ChromeAppViewAsh::OnDisplayFileOpenDialog,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Unretained(app_view_),
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   title,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   filter,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   default_path,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   allow_multiple_files));
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDisplayFileSaveAsDialog(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MetroViewerHostMsg_SaveAsDialogParams& params) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_proxy_->PostTask(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnDisplayFileSaveAsDialog,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(app_view_),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   params));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnDisplayFolderPicker(const string16& title) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui_proxy_->PostTask(
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnDisplayFolderPicker,
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(app_view_),
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   title));
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void OnSetCursorPos(int x, int y) {
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    VLOG(1) << "In IPC OnSetCursorPos: " << x << ", " << y;
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_proxy_->PostTask(
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        FROM_HERE,
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::Bind(&ChromeAppViewAsh::OnSetCursorPos,
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   base::Unretained(app_view_),
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   x, y));
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> ui_proxy_;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChromeAppViewAsh* app_view_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WaitForChromeIPCConnection(const std::string& channel_name) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int ms_elapsed = 0;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (!IPC::Channel::IsNamedServerInitialized(channel_name) &&
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ms_elapsed < 10000) {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ms_elapsed += 500;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Sleep(500);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IPC::Channel::IsNamedServerInitialized(channel_name);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class helps decoding the pointer properties of an event.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PointerInfoHandler {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointerInfoHandler() :
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x_(0),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y_(0),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wheel_delta_(0),
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_kind_(winui::Input::PointerUpdateKind_Other),
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      timestamp_(0),
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pointer_id_(0) {}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT Init(winui::Core::IPointerEventArgs* args) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = args->get_CurrentPoint(&pointer_point_);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winfoundtn::Point point;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = pointer_point_->get_Position(&point);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mswr::ComPtr<winui::Input::IPointerPointProperties> properties;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = pointer_point_->get_Properties(&properties);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = properties->get_PointerUpdateKind(&update_kind_);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = properties->get_MouseWheelDelta(&wheel_delta_);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x_ = point.X;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    y_ = point.Y;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pointer_point_->get_Timestamp(&timestamp_);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pointer_point_->get_PointerId(&pointer_id_);
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Map the OS touch event id to a range allowed by the gesture recognizer.
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsTouch())
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pointer_id_ %= ui::GestureSequence::kMaxGesturePoints;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsType(windevs::Input::PointerDeviceType type) const {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mswr::ComPtr<windevs::Input::IPointerDevice> pointer_device;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckHR(pointer_point_->get_PointerDevice(&pointer_device));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windevs::Input::PointerDeviceType device_type;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckHR(pointer_device->get_PointerDeviceType(&device_type));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return  (device_type == type);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsMouse() const {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IsType(windevs::Input::PointerDeviceType_Mouse);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsTouch() const {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IsType(windevs::Input::PointerDeviceType_Touch);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 wheel_delta() const {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return wheel_delta_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::EventFlags flags() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (update_kind_) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_LeftButtonPressed:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_LEFT_MOUSE_BUTTON;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_LeftButtonReleased:
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_LEFT_MOUSE_BUTTON;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_RightButtonPressed:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_RIGHT_MOUSE_BUTTON;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_RightButtonReleased:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_RIGHT_MOUSE_BUTTON;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_MiddleButtonPressed:
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_MIDDLE_MOUSE_BUTTON;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case winui::Input::PointerUpdateKind_MiddleButtonReleased:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_MIDDLE_MOUSE_BUTTON;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ui::EF_NONE;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x() const { return x_; }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y() const { return y_; }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 pointer_id() const {
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return pointer_id_;
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 timestamp() const { return timestamp_; }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x_;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int wheel_delta_;
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 pointer_id_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Input::PointerUpdateKind update_kind_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winui::Input::IPointerPoint> pointer_point_;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 timestamp_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're entering a nested message loop, let's allow dispatching
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tasks while we're in there.
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->SetNestableTasksAllowed(true);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter main core message loop. There are several ways to exit it
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nicely:
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 - User action like ALT-F4.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 - Calling ICoreApplicationExit::Exit().
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3-  Posting WM_CLOSE to the core window.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = dispatcher->ProcessEvents(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winui::Core::CoreProcessEventsOption
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ::CoreProcessEventsOption_ProcessUntilQuit);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wind down the thread's chrome message loop.
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Quit();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper to return the state of the shift/control/alt keys.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 GetKeyboardEventFlags() {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 flags = 0;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsShiftPressed())
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_SHIFT_DOWN;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsCtrlPressed())
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_CONTROL_DOWN;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsAltPressed())
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_ALT_DOWN;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return flags;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::ChromeAppViewAsh()
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : mouse_down_flags_(ui::EF_NONE),
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui_channel_(nullptr),
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      core_window_hwnd_(NULL),
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ui_loop_(base::MessageLoop::TYPE_UI) {
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  globals.previous_state =
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winapp::Activation::ApplicationExecutionState_NotRunning;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::~ChromeAppViewAsh() {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = view;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnActivate).Get(),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &activated_token_);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = window;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Retrieve the native window handle via the interop layer.
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mswr::ComPtr<ICoreWindowInterop> interop;
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = window->QueryInterface(interop.GetAddressOf());
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = interop->get_WindowHandle(&core_window_hwnd_);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  hr = window_->add_SizeChanged(mswr::Callback<SizeChangedHandler>(
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      this, &ChromeAppViewAsh::OnSizeChanged).Get(),
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      &sizechange_token_);
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckHR(hr);
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register for pointer and keyboard notifications. We forward
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them to the browser process via IPC.
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = window_->add_PointerMoved(mswr::Callback<PointerEventHandler>(
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerMoved).Get(),
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointermoved_token_);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerPressed(mswr::Callback<PointerEventHandler>(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerPressed).Get(),
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointerpressed_token_);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerReleased(mswr::Callback<PointerEventHandler>(
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnPointerReleased).Get(),
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &pointerreleased_token_);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_KeyDown(mswr::Callback<KeyEventHandler>(
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnKeyDown).Get(),
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keydown_token_);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_KeyUp(mswr::Callback<KeyEventHandler>(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnKeyUp).Get(),
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keyup_token_);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = window_->get_Dispatcher(&dispatcher);
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr, "Get Dispatcher failed.");
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreAcceleratorKeys> accelerator_keys;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = dispatcher.CopyTo(__uuidof(winui::Core::ICoreAcceleratorKeys),
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         reinterpret_cast<void**>(
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            accelerator_keys.GetAddressOf()));
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr, "QI for ICoreAcceleratorKeys failed.");
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = accelerator_keys->add_AcceleratorKeyActivated(
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mswr::Callback<AcceleratorKeyEventHandler>(
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ChromeAppViewAsh::OnAcceleratorKeyDown).Get(),
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &accel_keydown_token_);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_PointerWheelChanged(mswr::Callback<PointerEventHandler>(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnWheel).Get(),
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &wheel_token_);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->add_CharacterReceived(mswr::Callback<CharEventHandler>(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, &ChromeAppViewAsh::OnCharacterReceived).Get(),
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &character_received_token_);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = window_->add_VisibilityChanged(mswr::Callback<VisibilityChangedHandler>(
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, &ChromeAppViewAsh::OnVisibilityChanged).Get(),
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &visibility_changed_token_);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = window_->add_Activated(mswr::Callback<WindowActivatedHandler>(
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      this, &ChromeAppViewAsh::OnWindowActivated).Get(),
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &window_activated_token_);
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckHR(hr);
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By initializing the direct 3D swap chain with the corewindow
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can now directly blit to it from the browser process.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  direct3d_helper_.Initialize(window);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Initialized Direct3D.";
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Load(HSTRING entryPoint) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Run() {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = window_->get_Dispatcher(&dispatcher);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(hr, "Dispatcher failed.");
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = window_->Activate();
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr)) {
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DLOG(WARNING) << "activation failed hr=" << hr;
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return hr;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the IPC channel IO thread. It needs to out-live the ChannelProxy.
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Thread io_thread("metro_IO_thread");
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread::Options options;
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  options.message_loop_type = base::MessageLoop::TYPE_IO;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  io_thread.StartWithOptions(options);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start up Chrome and wait for the desired IPC server connection to exist.
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WaitForChromeIPCConnection(win8::kMetroViewerIPCChannelName);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In Aura mode we create an IPC channel to the browser, then ask it to
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect to us.
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ChromeChannelListener ui_channel_listener(&ui_loop_, this);
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  IPC::ChannelProxy ui_channel(win8::kMetroViewerIPCChannelName,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               IPC::Channel::MODE_NAMED_CLIENT,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &ui_channel_listener,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               io_thread.message_loop_proxy());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_ = &ui_channel;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // browser will use D3D from the browser process to present to our Window.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface(
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    gfx::NativeViewId(core_window_hwnd_)));
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Send an initial size message so that the Ash root window host gets sized
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // correctly.
4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  RECT rect = {0};
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ::GetWindowRect(core_window_hwnd_, &rect);
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_channel_->Send(
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left,
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                               rect.bottom - rect.top));
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And post the task that'll do the inner Metro message pumping to it.
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get()));
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.Run();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(0) << "ProcessEvents done, hr=" << hr;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewAsh::Uninitialize() {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = nullptr;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = nullptr;
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  core_window_hwnd_ = NULL;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::Unsnap() {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hr = winrt_utils::CreateActivationFactory(
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RuntimeClass_Windows_UI_ViewManagement_ApplicationView,
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      view_statics.GetAddressOf());
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::ViewManagement::ApplicationViewState state =
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      winui::ViewManagement::ApplicationViewState_FullScreenLandscape;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = view_statics->get_Value(&state);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckHR(hr);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state == winui::ViewManagement::ApplicationViewState_Snapped) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    boolean success = FALSE;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    hr = view_statics->TryUnsnap(&success);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (FAILED(hr) || !success) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Failed to unsnap. Error 0x" << hr;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (SUCCEEDED(hr))
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        hr = E_UNEXPECTED;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return hr;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnSetCursor(HCURSOR cursor) {
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ::SetCursor(HCURSOR(cursor));
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ChromeAppViewAsh::OnDisplayFileOpenDialog(
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const string16& title,
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const string16& filter,
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& default_path,
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool allow_multiple_files) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The OpenFilePickerSession instance is deleted when we receive a
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callback from the OpenFilePickerSession class about the completion of the
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // operation.
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ =
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OpenFilePickerSession(this,
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                title,
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                filter,
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                default_path,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                allow_multiple_files);
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnDisplayFileSaveAsDialog(
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MetroViewerHostMsg_SaveAsDialogParams& params) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The SaveFilePickerSession instance is deleted when we receive a
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // callback from the SaveFilePickerSession class about the completion of the
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // operation.
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ =
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new SaveFilePickerSession(this, params);
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ChromeAppViewAsh::OnDisplayFolderPicker(const string16& title) {
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The FolderPickerSession instance is deleted when we receive a
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // callback from the FolderPickerSession class about the completion of the
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // operation.
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePickerSessionBase* file_picker_ = new FolderPickerSession(this, title);
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_picker_->Run();
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
550b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ChromeAppViewAsh::OnSetCursorPos(int x, int y) {
551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (ui_channel_) {
552b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ::SetCursorPos(x, y);
553b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DVLOG(1) << "In UI OnSetCursorPos: " << x << ", " << y;
554b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_SetCursorPosAck());
555b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Generate a fake mouse move which matches the SetCursor coordinates as
556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // the browser expects to receive a mouse move for these coordinates.
557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // It is not clear why we don't receive a real mouse move in response to
558b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // the SetCursorPos calll above.
559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(x, y, 0));
560b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
561b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
562b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnOpenFileCompleted(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OpenFilePickerSession* open_file_picker,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ui_channel_) {
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (open_file_picker->allow_multi_select()) {
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_MultiFileOpenDone(
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success, open_file_picker->filenames()));
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_FileOpenDone(
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          success, base::FilePath(open_file_picker->result())));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete open_file_picker;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeAppViewAsh::OnSaveFileCompleted(
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SaveFilePickerSession* save_file_picker,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ui_channel_) {
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_FileSaveAsDone(
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        success,
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::FilePath(save_file_picker->result()),
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        save_file_picker->filter_index()));
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete save_file_picker;
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ChromeAppViewAsh::OnFolderPickerCompleted(
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FolderPickerSession* folder_picker,
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success) {
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << "Success: " << success;
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ui_channel_) {
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_SelectFolderDone(
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        success,
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::FilePath(folder_picker->result())));
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete folder_picker;
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnActivate(
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winapp::Core::ICoreApplicationView*,
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: If doing more work in this function, you migth need to call
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // get_PreviousExecutionState() and skip the work if  the result is
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ApplicationExecutionState_Running and globals.previous_state is too.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->get_PreviousExecutionState(&globals.previous_state);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Previous Execution State: " << globals.previous_state;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  winapp::Activation::ActivationKind activation_kind;
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->get_Kind(&activation_kind));
619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (activation_kind == winapp::Activation::ActivationKind_Search)
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    HandleSearchRequest(args);
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else if (activation_kind == winapp::Activation::ActivationKind_Protocol)
622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    HandleProtocolRequest(args);
623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We call ICoreWindow::Activate after the handling for the search/protocol
624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // requests because Chrome can be launched to handle a search request which
625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // in turn launches the chrome browser process in desktop mode via
626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // ShellExecute. If we call ICoreWindow::Activate before this, then
627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Windows kills the metro chrome process when it calls ShellExecute. Seems
628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // to be a bug.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Activate();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender,
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         winui::Core::IPointerEventArgs* args) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointerInfoHandler pointer;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(pointer.x(),
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        pointer.y(),
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        mouse_down_flags_));
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchMoved(pointer.x(),
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        pointer.y(),
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                        pointer.timestamp(),
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                        pointer.pointer_id()));
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE: From experimentation, it seems like Metro only sends a PointerPressed
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// event for the first button pressed and the last button released in a sequence
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of mouse events.
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For example, a sequence of LEFT_DOWN, RIGHT_DOWN, LEFT_UP, RIGHT_UP results
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// only in PointerPressed(LEFT)/PointerReleased(RIGHT) events.
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerPressed(
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointerInfoHandler pointer;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mouse_down_flags_ = pointer.flags();
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(),
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         pointer.y(),
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         0,
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         ui::ET_MOUSE_PRESSED,
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         mouse_down_flags_));
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchDown(pointer.x(),
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       pointer.y(),
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       pointer.timestamp(),
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       pointer.pointer_id()));
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnPointerReleased(
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointerInfoHandler pointer;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pointer.IsMouse()) {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mouse_down_flags_ = ui::EF_NONE;
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(),
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         pointer.y(),
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         0,
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         ui::ET_MOUSE_RELEASED,
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         pointer.flags()));
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(pointer.IsTouch());
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_channel_->Send(new MetroViewerHostMsg_TouchUp(pointer.x(),
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     pointer.y(),
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                     pointer.timestamp(),
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                     pointer.pointer_id()));
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnWheel(
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winui::Core::IPointerEventArgs* args) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointerInfoHandler pointer;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = pointer.Init(args);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pointer.IsMouse());
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(), pointer.y(),
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       pointer.wheel_delta(),
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       ui::ET_MOUSEWHEEL,
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       ui::EF_NONE));
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnKeyDown(
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IKeyEventArgs* args) {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winsys::VirtualKey virtual_key;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   status.RepeatCount,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   status.ScanCode,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   GetKeyboardEventFlags()));
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnKeyUp(
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IKeyEventArgs* args) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winsys::VirtualKey virtual_key;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key,
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 status.RepeatCount,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 status.ScanCode,
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 GetKeyboardEventFlags()));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown(
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreDispatcher* sender,
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IAcceleratorKeyEventArgs* args) {
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winsys::VirtualKey virtual_key;
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hr = args->get_VirtualKey(&virtual_key);
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = args->get_KeyStatus(&status);
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  winui::Core::CoreAcceleratorKeyEventType event_type;
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hr = args->get_EventType(&event_type);
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  uint32 keyboard_flags = GetKeyboardEventFlags();
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (event_type) {
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemCharacter:
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_Character(virtual_key,
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         status.RepeatCount,
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         status.ScanCode,
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                         keyboard_flags));
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown:
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key,
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       status.RepeatCount,
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       status.ScanCode,
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       keyboard_flags));
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp:
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key,
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     status.RepeatCount,
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     status.ScanCode,
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     keyboard_flags));
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return S_OK;
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnCharacterReceived(
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::ICoreWindow* sender,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::ICharacterReceivedEventArgs* args) {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int char_code = 0;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = args->get_KeyCode(&char_code);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  winui::Core::CorePhysicalKeyStatus status;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = args->get_KeyStatus(&status);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_Character(char_code,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     status.RepeatCount,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     status.ScanCode,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     GetKeyboardEventFlags()));
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnVisibilityChanged(
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    winui::Core::IVisibilityChangedEventArgs* args) {
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  boolean visible = false;
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hr = args->get_Visible(&visible);
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FAILED(hr))
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_VisibilityChanged(!!visible));
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return S_OK;
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HRESULT ChromeAppViewAsh::OnWindowActivated(
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::ICoreWindow* sender,
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    winui::Core::IWindowActivatedEventArgs* args) {
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  winui::Core::CoreWindowActivationState state;
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = args->get_WindowActivationState(&state);
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return hr;
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << "Window activation state: "  << state;
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_WindowActivated(
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      state != winui::Core::CoreWindowActivationState_Deactivated));
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return S_OK;
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)HRESULT ChromeAppViewAsh::HandleSearchRequest(
855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args;
857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->QueryInterface(
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          winapp::Activation::IID_ISearchActivatedEventArgs, &search_args));
859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!ui_channel_) {
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DVLOG(1) << "Launched to handle search request";
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::FilePath chrome_exe_path;
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!PathService::Get(base::FILE_EXE, &chrome_exe_path))
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return E_FAIL;
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SHELLEXECUTEINFO sei = { sizeof(sei) };
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sei.nShow = SW_SHOWNORMAL;
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sei.lpFile = chrome_exe_path.value().c_str();
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sei.lpDirectory = L"";
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sei.lpParameters =
872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        L"--silent-launch --viewer-connection=viewer --windows8-search";
873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ::ShellExecuteEx(&sei);
874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswrw::HString search_string;
877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(search_args->get_QueryText(search_string.GetAddressOf()));
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  string16 search_text(MakeStdWString(search_string.Get()));
879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE,
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Bind(&ChromeAppViewAsh::OnSearchRequest,
882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Unretained(this),
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    search_text));
884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return S_OK;
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)HRESULT ChromeAppViewAsh::HandleProtocolRequest(
888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    winapp::Activation::IActivatedEventArgs* args) {
889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!ui_channel_)
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DVLOG(1) << "Launched to handle url request";
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs>
894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      protocol_args;
895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckHR(args->QueryInterface(
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          winapp::Activation::IID_IProtocolActivatedEventArgs,
897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &protocol_args));
898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri;
900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  protocol_args->get_Uri(&uri);
901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mswrw::HString url;
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uri->get_AbsoluteUri(url.GetAddressOf());
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  string16 actual_url(MakeStdWString(url.Get()));
904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DVLOG(1) << "Received url request: " << actual_url;
905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_loop_.PostTask(FROM_HERE,
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    base::Bind(&ChromeAppViewAsh::OnNavigateToUrl,
908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               base::Unretained(this),
909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               actual_url));
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return S_OK;
911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ChromeAppViewAsh::OnSearchRequest(const string16& search_string) {
914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(ui_channel_);
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string));
916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ChromeAppViewAsh::OnNavigateToUrl(const string16& url) {
919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(ui_channel_);
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url));
921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender,
9247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    winui::Core::IWindowSizeChangedEventArgs* args) {
9257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!window_) {
9267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return S_OK;
9277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
9287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  winfoundtn::Size size;
9307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HRESULT hr = args->get_Size(&size);
9317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (FAILED(hr))
9327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return hr;
9337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  uint32 cx = static_cast<uint32>(size.Width);
9357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  uint32 cy = static_cast<uint32>(size.Height);
9367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DVLOG(1) << "Window size changed: width=" << cx << ", height=" << cy;
9387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_channel_->Send(new MetroViewerHostMsg_WindowSizeChanged(cx, cy));
9397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return S_OK;
9407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewFactory::ChromeAppViewFactory(
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    winapp::Core::ICoreApplication* icore_app,
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LPTHREAD_START_ROUTINE host_main,
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* host_context) {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckHR(core_app.As(&app_exit));
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  globals.app_exit = app_exit.Detach();
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IFACEMETHODIMP
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) {
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *view = mswr::Make<ChromeAppViewAsh>().Detach();
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (*view) ? S_OK :  E_OUTOFMEMORY;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
959