| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2010 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 CHROME_FRAME_TEST_IE_EVENT_SINK_H_ |
| 6 #define CHROME_FRAME_TEST_IE_EVENT_SINK_H_ |
| 7 |
| 8 #include <atlbase.h> |
| 9 #include <atlwin.h> |
| 10 #include <exdispid.h> |
| 11 #include <string> |
| 12 |
| 13 #include "base/lock.h" |
| 14 #include "base/scoped_comptr_win.h" |
| 15 |
| 16 #include "chrome_frame/test_utils.h" |
| 17 #include "chrome_frame/test/simulate_input.h" |
| 18 |
| 19 // Include without path to make GYP build see it. |
| 20 #include "chrome_tab.h" // NOLINT |
| 21 |
| 22 namespace chrome_frame_test { |
| 23 |
| 24 // Listener for all events from the IEEventSink, defined below. This includes |
| 25 // IE and CF events. Unfortunately some of these events are unreliable or have |
| 26 // strange behavior across different platforms/browsers. See notes besides |
| 27 // each method. |
| 28 class IEEventListener { |
| 29 public: |
| 30 virtual ~IEEventListener() {} |
| 31 |
| 32 // IE callbacks |
| 33 virtual void OnNavigateError(IDispatch* dispatch, VARIANT* url, |
| 34 VARIANT* frame_name, VARIANT* status_code, |
| 35 VARIANT* cancel) {} |
| 36 // This does not occur in IE 6 in CF when navigating between fragments |
| 37 // on the same page, although it does occur with back/forward across such. |
| 38 virtual void OnBeforeNavigate2(IDispatch* dispatch, VARIANT* url, |
| 39 VARIANT* flags, VARIANT* target_frame_name, |
| 40 VARIANT* post_data, VARIANT* headers, |
| 41 VARIANT_BOOL* cancel) {} |
| 42 virtual void OnDownloadBegin() {} |
| 43 virtual void OnNavigateComplete2(IDispatch* dispatch, VARIANT* url) {} |
| 44 virtual void OnNewWindow2(IDispatch** dispatch, VARIANT_BOOL* cancel) {} |
| 45 virtual void OnNewWindow3(IDispatch** dispatch, VARIANT_BOOL* cancel, |
| 46 DWORD flags, BSTR url_context, BSTR url) {} |
| 47 // This occurs twice on IE >= 7 after window.open calls. |
| 48 virtual void OnDocumentComplete(IDispatch* dispatch, VARIANT* url_variant) {} |
| 49 virtual void OnFileDownload(VARIANT_BOOL active_doc, VARIANT_BOOL* cancel) {} |
| 50 virtual void OnQuit() {} |
| 51 |
| 52 // CF callbacks |
| 53 virtual void OnLoad(const wchar_t* url) {} |
| 54 virtual void OnLoadError(const wchar_t* url) {} |
| 55 virtual void OnMessage(const wchar_t* message, const wchar_t* origin, |
| 56 const wchar_t* source) {} |
| 57 virtual void OnNewBrowserWindow(IDispatch* new_window, const wchar_t* url) {} |
| 58 }; |
| 59 |
| 60 // This class sets up event sinks to the IWebBrowser interface. It forwards |
| 61 // all events to its listener. |
| 62 // TODO(kkania): Delete WebBrowserEventSink and use this class instead for |
| 63 // the reliability tests. |
| 64 class IEEventSink |
| 65 : public CComObjectRootEx<CComSingleThreadModel>, |
| 66 public IDispEventSimpleImpl<0, IEEventSink, |
| 67 &DIID_DWebBrowserEvents2>, |
| 68 public IUnknown { |
| 69 public: |
| 70 // Needed to support PostTask. |
| 71 static bool ImplementsThreadSafeReferenceCounting() { |
| 72 return true; |
| 73 } |
| 74 |
| 75 typedef IDispEventSimpleImpl<0, IEEventSink, |
| 76 &DIID_DWebBrowserEvents2> DispEventsImpl; |
| 77 IEEventSink(); |
| 78 ~IEEventSink(); |
| 79 |
| 80 // Listen to events from this |browser_disp|, which should be queryable for |
| 81 // IWebBrowser2. |
| 82 void Attach(IDispatch* browser_disp); |
| 83 |
| 84 // Stop listening to the associated web browser and possibly wait for it to |
| 85 // close, if this browser has its own process. |
| 86 void Uninitialize(); |
| 87 |
| 88 // Closes the web browser in such a way that the OnQuit notification will |
| 89 // be fired when the window closes (async). |
| 90 HRESULT CloseWebBrowser(); |
| 91 |
| 92 // Set input focus to chrome frame window. |
| 93 void SetFocusToRenderer(); |
| 94 |
| 95 // Send keyboard input to the renderer window hosted in chrome using |
| 96 // SendInput API. |
| 97 void SendKeys(const wchar_t* input_string); |
| 98 |
| 99 // Send mouse click to the renderer window hosted in chrome using |
| 100 // SendInput API. |
| 101 void SendMouseClick(int x, int y, simulate_input::MouseButton button); |
| 102 |
| 103 // Get the HWND for the browser's renderer window. |
| 104 HWND GetRendererWindow(); |
| 105 |
| 106 // Launch IE, use the given listener, and navigate to the given url. |
| 107 HRESULT LaunchIEAndNavigate(const std::wstring& navigate_url, |
| 108 IEEventListener* listener); |
| 109 |
| 110 // Navigate to the given url. |
| 111 HRESULT Navigate(const std::wstring& navigate_url); |
| 112 |
| 113 // Returns whether CF is rendering the current page. |
| 114 bool IsCFRendering(); |
| 115 |
| 116 // Expect the renderer window to have focus. |
| 117 void ExpectRendererWindowHasFocus(); |
| 118 |
| 119 // Expect the address bar to have |url|. |
| 120 void ExpectAddressBarUrl(const std::wstring& url); |
| 121 |
| 122 // These methods are just simple wrappers of the IWebBrowser2 methods. |
| 123 // They are needed because you cannot post tasks to IWebBrowser2. |
| 124 void GoBack() { |
| 125 web_browser2_->GoBack(); |
| 126 } |
| 127 |
| 128 void GoForward() { |
| 129 web_browser2_->GoForward(); |
| 130 } |
| 131 |
| 132 void Refresh(); |
| 133 |
| 134 void Exec(const GUID* cmd_group_guid, DWORD command_id, |
| 135 DWORD cmd_exec_opt, VARIANT* in_args, VARIANT* out_args); |
| 136 |
| 137 // Set the listener for this sink, which can be NULL. |
| 138 void set_listener(IEEventListener* listener) { listener_ = listener; } |
| 139 |
| 140 IWebBrowser2* web_browser2() { return web_browser2_.get(); } |
| 141 |
| 142 // Used only for debugging/logging purposes. |
| 143 bool IsReferenceCountOne() { return m_dwRef == 1; } |
| 144 |
| 145 private: |
| 146 void ConnectToChromeFrame(); |
| 147 void DisconnectFromChromeFrame(); |
| 148 void FindIEProcessId(); |
| 149 |
| 150 // IE callbacks. |
| 151 BEGIN_COM_MAP(IEEventSink) |
| 152 COM_INTERFACE_ENTRY(IUnknown) |
| 153 END_COM_MAP() |
| 154 |
| 155 BEGIN_SINK_MAP(IEEventSink) |
| 156 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, |
| 157 OnBeforeNavigate2, &kBeforeNavigate2Info) |
| 158 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOWNLOADBEGIN, |
| 159 OnDownloadBegin, &kVoidMethodInfo) |
| 160 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2, |
| 161 OnNavigateComplete2, &kNavigateComplete2Info) |
| 162 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR, |
| 163 OnNavigateError, &kNavigateErrorInfo) |
| 164 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW2, |
| 165 OnNewWindow2, &kNewWindow2Info) |
| 166 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3, |
| 167 OnNewWindow3, &kNewWindow3Info) |
| 168 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, |
| 169 OnDocumentComplete, &kDocumentCompleteInfo) |
| 170 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_FILEDOWNLOAD, |
| 171 OnFileDownload, &kFileDownloadInfo) |
| 172 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_ONQUIT, |
| 173 OnQuit, &kVoidMethodInfo) |
| 174 END_SINK_MAP() |
| 175 |
| 176 STDMETHOD_(void, OnNavigateError)(IDispatch* dispatch, VARIANT* url, |
| 177 VARIANT* frame_name, VARIANT* status_code, |
| 178 VARIANT* cancel); |
| 179 STDMETHOD(OnBeforeNavigate2)(IDispatch* dispatch, VARIANT* url, |
| 180 VARIANT* flags, VARIANT* target_frame_name, |
| 181 VARIANT* post_data, VARIANT* headers, |
| 182 VARIANT_BOOL* cancel); |
| 183 STDMETHOD_(void, OnDownloadBegin)(); |
| 184 STDMETHOD_(void, OnNavigateComplete2)(IDispatch* dispatch, VARIANT* url); |
| 185 STDMETHOD_(void, OnNewWindow2)(IDispatch** dispatch, VARIANT_BOOL* cancel); |
| 186 STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* cancel, |
| 187 DWORD flags, BSTR url_context, BSTR url); |
| 188 STDMETHOD_(void, OnDocumentComplete)(IDispatch* dispatch, |
| 189 VARIANT* url_variant); |
| 190 STDMETHOD_(void, OnFileDownload)(VARIANT_BOOL active_doc, |
| 191 VARIANT_BOOL* cancel); |
| 192 STDMETHOD_(void, OnQuit)(); |
| 193 |
| 194 #ifdef _DEBUG |
| 195 STDMETHOD(Invoke)(DISPID dispid, REFIID riid, |
| 196 LCID lcid, WORD flags, DISPPARAMS* params, VARIANT* result, |
| 197 EXCEPINFO* except_info, UINT* arg_error) { |
| 198 DLOG(INFO) << __FUNCTION__ << L" disp id :" << dispid; |
| 199 return DispEventsImpl::Invoke(dispid, riid, lcid, flags, params, result, |
| 200 except_info, arg_error); |
| 201 } |
| 202 #endif // _DEBUG |
| 203 |
| 204 // IChromeFrame callbacks |
| 205 HRESULT OnLoad(const VARIANT* param); |
| 206 HRESULT OnLoadError(const VARIANT* param); |
| 207 HRESULT OnMessage(const VARIANT* param); |
| 208 |
| 209 ScopedComPtr<IWebBrowser2> web_browser2_; |
| 210 ScopedComPtr<IChromeFrame> chrome_frame_; |
| 211 DispCallback<IEEventSink> onmessage_; |
| 212 DispCallback<IEEventSink> onloaderror_; |
| 213 DispCallback<IEEventSink> onload_; |
| 214 IEEventListener* listener_; |
| 215 base::ProcessId ie_process_id_; |
| 216 bool did_receive_on_quit_; |
| 217 |
| 218 static _ATL_FUNC_INFO kBeforeNavigate2Info; |
| 219 static _ATL_FUNC_INFO kNavigateComplete2Info; |
| 220 static _ATL_FUNC_INFO kNavigateErrorInfo; |
| 221 static _ATL_FUNC_INFO kNewWindow2Info; |
| 222 static _ATL_FUNC_INFO kNewWindow3Info; |
| 223 static _ATL_FUNC_INFO kVoidMethodInfo; |
| 224 static _ATL_FUNC_INFO kDocumentCompleteInfo; |
| 225 static _ATL_FUNC_INFO kFileDownloadInfo; |
| 226 }; |
| 227 |
| 228 } // namespace chrome_frame_test |
| 229 |
| 230 #endif // CHROME_FRAME_TEST_IE_EVENT_SINK_H_ |
| OLD | NEW |