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