1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_
6#define WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_
7
8#include <windows.applicationmodel.core.h>
9#include <windows.ui.core.h>
10#include <windows.ui.input.h>
11#include <windows.ui.viewmanagement.h>
12
13#include "base/memory/scoped_ptr.h"
14#include "base/message_loop/message_loop.h"
15#include "base/strings/string16.h"
16#include "base/threading/thread.h"
17#include "ipc/ipc_listener.h"
18#include "ui/events/event_constants.h"
19#include "win8/metro_driver/direct3d_helper.h"
20#include "win8/metro_driver/ime/ime_popup_observer.h"
21#include "win8/metro_driver/ime/input_source_observer.h"
22#include "win8/metro_driver/ime/text_service_delegate.h"
23
24namespace base {
25class FilePath;
26}
27
28namespace IPC {
29class Listener;
30class ChannelProxy;
31}
32
33namespace metro_driver {
34class InputSource;
35class TextService;
36}
37
38namespace metro_viewer {
39struct CharacterBounds;
40struct UnderlineInfo;
41}
42
43class OpenFilePickerSession;
44class SaveFilePickerSession;
45class FolderPickerSession;
46class FilePickerSessionBase;
47
48struct MetroViewerHostMsg_SaveAsDialogParams;
49
50enum MetroTerminateMethod {
51  TERMINATE_USING_KEY_SEQUENCE = 1,
52  TERMINATE_USING_PROCESS_EXIT = 2,
53};
54
55class ChromeAppViewAsh
56    : public mswr::RuntimeClass<winapp::Core::IFrameworkView>,
57      public metro_driver::ImePopupObserver,
58      public metro_driver::InputSourceObserver,
59      public metro_driver::TextServiceDelegate {
60 public:
61  ChromeAppViewAsh();
62  ~ChromeAppViewAsh();
63
64  // IViewProvider overrides.
65  IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view);
66  IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window);
67  IFACEMETHOD(Load)(HSTRING entryPoint);
68  IFACEMETHOD(Run)();
69  IFACEMETHOD(Uninitialize)();
70
71  // Helper function to unsnap the chrome metro app if it is snapped.
72  // Returns S_OK on success.
73  static HRESULT Unsnap();
74
75  void OnActivateDesktop(const base::FilePath& file_path, bool ash_exit);
76  void OnOpenURLOnDesktop(const base::FilePath& shortcut,
77                          const base::string16& url);
78  void OnSetCursor(HCURSOR cursor);
79  void OnDisplayFileOpenDialog(const base::string16& title,
80                               const base::string16& filter,
81                               const base::FilePath& default_path,
82                               bool allow_multiple_files);
83  void OnDisplayFileSaveAsDialog(
84      const MetroViewerHostMsg_SaveAsDialogParams& params);
85  void OnDisplayFolderPicker(const base::string16& title);
86  void OnSetCursorPos(int x, int y);
87
88  // This function is invoked when the open file operation completes. The
89  // result of the operation is passed in along with the OpenFilePickerSession
90  // instance which is deleted after we read the required information from
91  // the OpenFilePickerSession class.
92  void OnOpenFileCompleted(OpenFilePickerSession* open_file_picker,
93                           bool success);
94
95  // This function is invoked when the save file operation completes. The
96  // result of the operation is passed in along with the SaveFilePickerSession
97  // instance which is deleted after we read the required information from
98  // the SaveFilePickerSession class.
99  void OnSaveFileCompleted(SaveFilePickerSession* save_file_picker,
100                           bool success);
101
102  // This function is invoked when the folder picker operation completes. The
103  // result of the operation is passed in along with the FolderPickerSession
104  // instance which is deleted after we read the required information from
105  // the FolderPickerSession class.
106  void OnFolderPickerCompleted(FolderPickerSession* folder_picker,
107                               bool success);
108
109  void OnImeCancelComposition();
110  void OnImeUpdateTextInputClient(
111      const std::vector<int32>& input_scopes,
112      const std::vector<metro_viewer::CharacterBounds>& character_bounds);
113
114  void OnMetroExit(MetroTerminateMethod method);
115
116  HWND core_window_hwnd() const { return  core_window_hwnd_; }
117
118
119 private:
120  class PointerInfoHandler;
121
122  // ImePopupObserver overrides.
123  virtual void OnImePopupChanged(ImePopupObserver::EventType event) OVERRIDE;
124
125  // InputSourceObserver overrides.
126  virtual void OnInputSourceChanged() OVERRIDE;
127
128  // TextServiceDelegate overrides.
129  virtual void OnCompositionChanged(
130      const base::string16& text,
131      int32 selection_start,
132      int32 selection_end,
133      const std::vector<metro_viewer::UnderlineInfo>& underlines) OVERRIDE;
134  virtual void OnTextCommitted(const base::string16& text) OVERRIDE;
135
136  // Convenience for sending a MetroViewerHostMsg_MouseButton with the specified
137  // parameters.
138  void SendMouseButton(int x,
139                       int y,
140                       int extra,
141                       ui::EventType event_type,
142                       uint32 flags,
143                       ui::EventFlags changed_button,
144                       bool is_horizontal_wheel);
145
146  // Win8 only generates a mouse press for the initial button that goes down and
147  // a release when the last button is released. Any intermediary presses (or
148  // releases) do not result in a new press/release event. Instead a move is
149  // generated with the winui::Input::PointerUpdateKind identifying what
150  // changed. This function generates the necessary intermediary events (as
151  // necessary).
152  void GenerateMouseEventFromMoveIfNecessary(const PointerInfoHandler& pointer);
153
154  HRESULT OnActivate(winapp::Core::ICoreApplicationView* view,
155                     winapp::Activation::IActivatedEventArgs* args);
156
157  HRESULT OnPointerMoved(winui::Core::ICoreWindow* sender,
158                         winui::Core::IPointerEventArgs* args);
159
160  HRESULT OnPointerPressed(winui::Core::ICoreWindow* sender,
161                           winui::Core::IPointerEventArgs* args);
162
163  HRESULT OnPointerReleased(winui::Core::ICoreWindow* sender,
164                            winui::Core::IPointerEventArgs* args);
165
166  HRESULT OnWheel(winui::Core::ICoreWindow* sender,
167                  winui::Core::IPointerEventArgs* args);
168
169  HRESULT OnKeyDown(winui::Core::ICoreWindow* sender,
170                    winui::Core::IKeyEventArgs* args);
171
172  HRESULT OnKeyUp(winui::Core::ICoreWindow* sender,
173                  winui::Core::IKeyEventArgs* args);
174
175  // Invoked for system keys like Alt, etc.
176  HRESULT OnAcceleratorKeyDown(winui::Core::ICoreDispatcher* sender,
177                               winui::Core::IAcceleratorKeyEventArgs* args);
178
179  HRESULT OnCharacterReceived(winui::Core::ICoreWindow* sender,
180                              winui::Core::ICharacterReceivedEventArgs* args);
181
182  HRESULT OnWindowActivated(winui::Core::ICoreWindow* sender,
183                            winui::Core::IWindowActivatedEventArgs* args);
184
185  // Helper to handle search requests received via the search charm in ASH.
186  HRESULT HandleSearchRequest(winapp::Activation::IActivatedEventArgs* args);
187  // Helper to handle http/https url requests in ASH.
188  HRESULT HandleProtocolRequest(winapp::Activation::IActivatedEventArgs* args);
189
190  HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture,
191                                 winui::Input::IEdgeGestureEventArgs* args);
192
193  // Tasks posted to the UI thread to initiate the search/url navigation
194  // requests.
195  void OnSearchRequest(const base::string16& search_string);
196  void OnNavigateToUrl(const base::string16& url);
197
198  HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender,
199                        winui::Core::IWindowSizeChangedEventArgs* args);
200
201  // This function checks if the Chrome browser channel is initialized. If yes
202  // then it goes ahead and starts up the viewer in Chrome OS mode. If not it
203  // posts a delayed task and checks again. It does this for a duration of 10
204  // seconds and then bails.
205  void StartChromeOSMode();
206
207  mswr::ComPtr<winui::Core::ICoreWindow> window_;
208  mswr::ComPtr<winapp::Core::ICoreApplicationView> view_;
209  EventRegistrationToken activated_token_;
210  EventRegistrationToken pointermoved_token_;
211  EventRegistrationToken pointerpressed_token_;
212  EventRegistrationToken pointerreleased_token_;
213  EventRegistrationToken wheel_token_;
214  EventRegistrationToken keydown_token_;
215  EventRegistrationToken keyup_token_;
216  EventRegistrationToken character_received_token_;
217  EventRegistrationToken accel_keydown_token_;
218  EventRegistrationToken accel_keyup_token_;
219  EventRegistrationToken window_activated_token_;
220  EventRegistrationToken sizechange_token_;
221  EventRegistrationToken edgeevent_token_;
222
223  // Keep state about which button is currently down, if any, as PointerMoved
224  // events do not contain that state, but Ash's MouseEvents need it. Value is
225  // as a bitmask of ui::EventFlags.
226  uint32 mouse_down_flags_;
227
228  // Set the D3D swap chain and nothing else.
229  metro_driver::Direct3DHelper direct3d_helper_;
230
231  // The IPC channel IO thread.
232  scoped_ptr<base::Thread> io_thread_;
233
234  // The channel to Chrome, in particular to the MetroViewerProcessHost.
235  scoped_ptr<IPC::ChannelProxy> ui_channel_;
236
237  // The actual window behind the view surface.
238  HWND core_window_hwnd_;
239
240  // UI message loop to allow message passing into this thread.
241  base::MessageLoopForUI ui_loop_;
242
243  // For IME support.
244  scoped_ptr<metro_driver::InputSource> input_source_;
245  scoped_ptr<metro_driver::TextService> text_service_;
246
247  // The metro device scale factor as reported by the winrt interfaces.
248  float metro_dpi_scale_;
249  // The win32 dpi scale which is queried via GetDeviceCaps. Please refer to
250  // ui/gfx/win/dpi.cc for more information.
251  float win32_dpi_scale_;
252
253  // The cursor set by the chroem browser process.
254  HCURSOR last_cursor_;
255
256  // Pointer to the channel listener for the channel between the viewer and
257  // the browser.
258  IPC::Listener* channel_listener_;
259};
260
261#endif  // WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_
262