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.
5 #ifndef CHROME_FRAME_TEST_IE_EVENT_SINK_H_
6 #define CHROME_FRAME_TEST_IE_EVENT_SINK_H_
13 #include "base/win/scoped_comptr.h"
14 #include "chrome_frame/chrome_tab.h"
15 #include "chrome_frame/test/simulate_input.h"
16 #include "chrome_frame/test_utils.h"
18 namespace chrome_frame_test
{
20 // Listener for all events from the IEEventSink, defined below. This includes
21 // IE and CF events. Unfortunately some of these events are unreliable or have
22 // strange behavior across different platforms/browsers. See notes besides
24 class IEEventListener
{
26 virtual ~IEEventListener() {}
29 virtual void OnNavigateError(IDispatch
* dispatch
, VARIANT
* url
,
30 VARIANT
* frame_name
, VARIANT
* status_code
,
32 // This does not occur in IE 6 in CF when navigating between fragments
33 // on the same page, although it does occur with back/forward across such.
34 virtual void OnBeforeNavigate2(IDispatch
* dispatch
, VARIANT
* url
,
35 VARIANT
* flags
, VARIANT
* target_frame_name
,
36 VARIANT
* post_data
, VARIANT
* headers
,
37 VARIANT_BOOL
* cancel
) {}
38 virtual void OnDownloadBegin() {}
39 virtual void OnNavigateComplete2(IDispatch
* dispatch
, VARIANT
* url
) {}
40 virtual void OnNewWindow2(IDispatch
** dispatch
, VARIANT_BOOL
* cancel
) {}
41 virtual void OnNewWindow3(IDispatch
** dispatch
, VARIANT_BOOL
* cancel
,
42 DWORD flags
, BSTR url_context
, BSTR url
) {}
43 // This occurs twice on IE >= 7 after window.open calls.
44 virtual void OnDocumentComplete(IDispatch
* dispatch
, VARIANT
* url_variant
) {}
45 virtual void OnFileDownload(VARIANT_BOOL active_doc
, VARIANT_BOOL
* cancel
) {}
46 virtual void OnQuit() {}
49 virtual void OnLoad(const wchar_t* url
) {}
50 virtual void OnLoadError(const wchar_t* url
) {}
51 virtual void OnMessage(const wchar_t* message
, const wchar_t* origin
,
52 const wchar_t* source
) {}
53 virtual void OnNewBrowserWindow(IDispatch
* new_window
, const wchar_t* url
) {}
56 // Listener for IPropertyNotifySink.
57 class PropertyNotifySinkListener
{
59 virtual ~PropertyNotifySinkListener() {}
60 virtual void OnChanged(DISPID dispid
) {}
61 virtual void OnRequestEdit(DISPID dispid
) {}
64 // This class sets up event sinks to the IWebBrowser interface. It forwards
65 // all events to its listener.
67 : public CComObjectRootEx
<CComSingleThreadModel
>,
68 public IDispEventSimpleImpl
<0, IEEventSink
,
69 &DIID_DWebBrowserEvents2
>,
72 // Needed to support PostTask.
73 static bool ImplementsThreadSafeReferenceCounting() {
77 typedef IDispEventSimpleImpl
<0, IEEventSink
,
78 &DIID_DWebBrowserEvents2
> DispEventsImpl
;
82 // Launches IE, sets up the sink to forward events to the listener, and
83 // navigates to the given page.
84 HRESULT
LaunchIEAndNavigate(const std::wstring
& navigate_url
,
85 IEEventListener
* listener
);
87 // Navigate to the given url.
88 HRESULT
Navigate(const std::wstring
& navigate_url
);
90 // Listen to events from this |browser_disp|, which should be queryable for
92 void Attach(IDispatch
* browser_disp
);
94 // Listen to events from the given browser.
95 HRESULT
Attach(IWebBrowser2
* browser
);
97 // Stop listening to the associated web browser and possibly wait for it to
98 // close, if this browser has its own process.
101 // Closes the web browser in such a way that the OnQuit notification will
102 // be fired when the window closes (async).
103 HRESULT
CloseWebBrowser();
105 // Posts a message to the given target in ChromeFrame. |target| may be "*".
106 void PostMessageToCF(const std::wstring
& message
, const std::wstring
& target
);
108 // Set input focus to chrome frame window.
109 void SetFocusToRenderer();
111 // Send keyboard input to the renderer window hosted in chrome using
113 void SendKeys(const wchar_t* input_string
);
115 // Send mouse click to the renderer window hosted in chrome using
117 void SendMouseClick(int x
, int y
, simulate_input::MouseButton button
);
119 // Get the HWND for the browser's main window. Will fail test if window
121 HWND
GetBrowserWindow();
123 // Get the HWND for the browser's renderer window. Will fail test if
124 // renderer window not found.
125 HWND
GetRendererWindow();
127 // Same as above, but does not fail the test if the window cannot be found.
128 // In that case, the returned handle will be NULL.
129 HWND
GetRendererWindowSafe();
131 // Returns whether CF is rendering the current page.
132 bool IsCFRendering();
134 // Expect the renderer window to have focus.
135 void ExpectRendererWindowHasFocus();
137 // Expect the address bar to have |url|.
138 void ExpectAddressBarUrl(const std::wstring
& url
);
140 // These methods are just simple wrappers of the IWebBrowser2 methods.
141 // They are needed because you cannot post tasks to IWebBrowser2.
143 web_browser2_
->GoBack();
147 web_browser2_
->GoForward();
152 void Exec(const GUID
* cmd_group_guid
, DWORD command_id
,
153 DWORD cmd_exec_opt
, VARIANT
* in_args
, VARIANT
* out_args
);
155 // Set the listener for this sink, which can be NULL.
156 void set_listener(IEEventListener
* listener
) { listener_
= listener
; }
158 IWebBrowser2
* web_browser2() { return web_browser2_
.get(); }
160 // Used only for debugging/logging purposes.
161 bool reference_count() { return m_dwRef
; }
163 static void SetAbnormalShutdown(bool abnormal_shutdown
);
166 void ConnectToChromeFrame();
167 void DisconnectFromChromeFrame();
168 void FindIEProcessId();
171 BEGIN_COM_MAP(IEEventSink
)
172 COM_INTERFACE_ENTRY(IUnknown
)
175 BEGIN_SINK_MAP(IEEventSink
)
176 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_BEFORENAVIGATE2
,
177 OnBeforeNavigate2
, &kBeforeNavigate2Info
)
178 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_DOWNLOADBEGIN
,
179 OnDownloadBegin
, &kVoidMethodInfo
)
180 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_NAVIGATECOMPLETE2
,
181 OnNavigateComplete2
, &kNavigateComplete2Info
)
182 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_NAVIGATEERROR
,
183 OnNavigateError
, &kNavigateErrorInfo
)
184 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_NEWWINDOW2
,
185 OnNewWindow2
, &kNewWindow2Info
)
186 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_NEWWINDOW3
,
187 OnNewWindow3
, &kNewWindow3Info
)
188 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_DOCUMENTCOMPLETE
,
189 OnDocumentComplete
, &kDocumentCompleteInfo
)
190 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_FILEDOWNLOAD
,
191 OnFileDownload
, &kFileDownloadInfo
)
192 SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2
, DISPID_ONQUIT
,
193 OnQuit
, &kVoidMethodInfo
)
196 STDMETHOD_(void, OnNavigateError
)(IDispatch
* dispatch
, VARIANT
* url
,
197 VARIANT
* frame_name
, VARIANT
* status_code
,
199 STDMETHOD(OnBeforeNavigate2
)(IDispatch
* dispatch
, VARIANT
* url
,
200 VARIANT
* flags
, VARIANT
* target_frame_name
,
201 VARIANT
* post_data
, VARIANT
* headers
,
202 VARIANT_BOOL
* cancel
);
203 STDMETHOD_(void, OnDownloadBegin
)();
204 STDMETHOD_(void, OnNavigateComplete2
)(IDispatch
* dispatch
, VARIANT
* url
);
205 STDMETHOD_(void, OnNewWindow2
)(IDispatch
** dispatch
, VARIANT_BOOL
* cancel
);
206 STDMETHOD_(void, OnNewWindow3
)(IDispatch
** dispatch
, VARIANT_BOOL
* cancel
,
207 DWORD flags
, BSTR url_context
, BSTR url
);
208 STDMETHOD_(void, OnDocumentComplete
)(IDispatch
* dispatch
,
209 VARIANT
* url_variant
);
210 STDMETHOD_(void, OnFileDownload
)(VARIANT_BOOL active_doc
,
211 VARIANT_BOOL
* cancel
);
212 STDMETHOD_(void, OnQuit
)();
214 STDMETHOD(Invoke
)(DISPID dispid
,
215 REFIID riid
, LCID lcid
,
219 EXCEPINFO
* except_info
,
222 // IChromeFrame callbacks
223 HRESULT
OnLoad(const VARIANT
* param
);
224 HRESULT
OnLoadError(const VARIANT
* param
);
225 HRESULT
OnMessage(const VARIANT
* param
);
227 base::win::ScopedComPtr
<IWebBrowser2
> web_browser2_
;
228 base::win::ScopedComPtr
<IChromeFrame
> chrome_frame_
;
229 DispCallback
<IEEventSink
> onmessage_
;
230 DispCallback
<IEEventSink
> onloaderror_
;
231 DispCallback
<IEEventSink
> onload_
;
232 IEEventListener
* listener_
;
233 base::ProcessId ie_process_id_
;
234 bool did_receive_on_quit_
;
235 static bool abnormal_shutdown_
;
237 static _ATL_FUNC_INFO kBeforeNavigate2Info
;
238 static _ATL_FUNC_INFO kNavigateComplete2Info
;
239 static _ATL_FUNC_INFO kNavigateErrorInfo
;
240 static _ATL_FUNC_INFO kNewWindow2Info
;
241 static _ATL_FUNC_INFO kNewWindow3Info
;
242 static _ATL_FUNC_INFO kVoidMethodInfo
;
243 static _ATL_FUNC_INFO kDocumentCompleteInfo
;
244 static _ATL_FUNC_INFO kFileDownloadInfo
;
247 class PropertyNotifySinkImpl
248 : public CComObjectRootEx
<CComSingleThreadModel
>,
249 public IPropertyNotifySink
{
251 PropertyNotifySinkImpl() : listener_(NULL
) {
254 BEGIN_COM_MAP(PropertyNotifySinkImpl
)
255 COM_INTERFACE_ENTRY(IPropertyNotifySink
)
258 STDMETHOD(OnChanged
)(DISPID dispid
) {
260 listener_
->OnChanged(dispid
);
264 STDMETHOD(OnRequestEdit
)(DISPID dispid
) {
266 listener_
->OnRequestEdit(dispid
);
270 void set_listener(PropertyNotifySinkListener
* listener
) {
271 DCHECK(listener_
== NULL
|| listener
== NULL
);
272 listener_
= listener
;
276 PropertyNotifySinkListener
* listener_
;
279 } // namespace chrome_frame_test
281 #endif // CHROME_FRAME_TEST_IE_EVENT_SINK_H_