|
1 /* |
|
2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY |
|
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
|
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
|
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
23 */ |
|
24 |
|
25 #include "HostWindow.h" |
|
26 #include "Test.h" |
|
27 #include <WebCore/COMPtr.h> |
|
28 #include <WebKit/WebKit.h> |
|
29 #include <WebKit/WebKitCOMAPI.h> |
|
30 #include <wtf/PassOwnPtr.h> |
|
31 |
|
32 namespace WebKitAPITest { |
|
33 |
|
34 template <typename T> |
|
35 static HRESULT WebKitCreateInstance(REFCLSID clsid, T** object) |
|
36 { |
|
37 return WebKitCreateInstance(clsid, 0, __uuidof(T), reinterpret_cast<void**>(object)); |
|
38 } |
|
39 |
|
40 static int webViewCount() |
|
41 { |
|
42 COMPtr<IWebKitStatistics> statistics; |
|
43 if (FAILED(WebKitCreateInstance(__uuidof(WebKitStatistics), &statistics))) |
|
44 return -1; |
|
45 int count; |
|
46 if (FAILED(statistics->webViewCount(&count))) |
|
47 return -1; |
|
48 return count; |
|
49 } |
|
50 |
|
51 static void createAndInitializeWebView(COMPtr<IWebView>& outWebView, HostWindow& window, HWND& viewWindow) |
|
52 { |
|
53 COMPtr<IWebView> webView; |
|
54 TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView))); |
|
55 |
|
56 TEST_ASSERT(window.initialize()); |
|
57 TEST_ASSERT(SUCCEEDED(webView->setHostWindow(reinterpret_cast<OLE_HANDLE>(window.window())))); |
|
58 TEST_ASSERT(SUCCEEDED(webView->initWithFrame(window.clientRect(), 0, 0))); |
|
59 |
|
60 COMPtr<IWebViewPrivate> viewPrivate(Query, webView); |
|
61 TEST_ASSERT(viewPrivate); |
|
62 TEST_ASSERT(SUCCEEDED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow)))); |
|
63 TEST_ASSERT(IsWindow(viewWindow)); |
|
64 |
|
65 outWebView.adoptRef(webView.releaseRef()); |
|
66 } |
|
67 |
|
68 static void runMessagePump(DWORD timeoutMilliseconds) |
|
69 { |
|
70 DWORD startTickCount = GetTickCount(); |
|
71 MSG msg; |
|
72 BOOL result; |
|
73 while ((result = PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) && GetTickCount() - startTickCount <= timeoutMilliseconds) { |
|
74 if (result == -1) |
|
75 break; |
|
76 TranslateMessage(&msg); |
|
77 DispatchMessage(&msg); |
|
78 } |
|
79 } |
|
80 |
|
81 static void finishWebViewDestructionTest(COMPtr<IWebView>& webView, HWND viewWindow) |
|
82 { |
|
83 // Allow window messages to be processed, because in some cases that would trigger a crash (e.g., <http://webkit.org/b/32827>). |
|
84 runMessagePump(50); |
|
85 |
|
86 // We haven't crashed. Release the WebView and ensure that its view window has been destroyed and the WebView doesn't leak. |
|
87 int currentWebViewCount = webViewCount(); |
|
88 TEST_ASSERT(currentWebViewCount > 0); |
|
89 |
|
90 webView = 0; |
|
91 |
|
92 TEST_ASSERT(webViewCount() == currentWebViewCount - 1); |
|
93 TEST_ASSERT(!IsWindow(viewWindow)); |
|
94 } |
|
95 |
|
96 // Tests that releasing a WebView without calling IWebView::initWithFrame works. |
|
97 TEST(WebViewDestruction, NoInitWithFrame) |
|
98 { |
|
99 COMPtr<IWebView> webView; |
|
100 TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView))); |
|
101 |
|
102 finishWebViewDestructionTest(webView, 0); |
|
103 } |
|
104 |
|
105 TEST(WebViewDestruction, CloseWithoutInitWithFrame) |
|
106 { |
|
107 COMPtr<IWebView> webView; |
|
108 TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView))); |
|
109 |
|
110 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
111 |
|
112 finishWebViewDestructionTest(webView, 0); |
|
113 } |
|
114 |
|
115 // Tests that releasing a WebView without calling IWebView::close or DestroyWindow doesn't leak. <http://webkit.org/b/33162> |
|
116 TEST(WebViewDestruction, NoCloseOrDestroyViewWindow) |
|
117 { |
|
118 COMPtr<IWebView> webView; |
|
119 HostWindow window; |
|
120 HWND viewWindow; |
|
121 createAndInitializeWebView(webView, window, viewWindow); |
|
122 |
|
123 finishWebViewDestructionTest(webView, viewWindow); |
|
124 } |
|
125 |
|
126 // Tests that calling IWebView::close without calling DestroyWindow, then releasing a WebView doesn't crash. <http://webkit.org/b/32827> |
|
127 TEST(WebViewDestruction, CloseWithoutDestroyViewWindow) |
|
128 { |
|
129 COMPtr<IWebView> webView; |
|
130 HostWindow window; |
|
131 HWND viewWindow; |
|
132 createAndInitializeWebView(webView, window, viewWindow); |
|
133 |
|
134 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
135 |
|
136 finishWebViewDestructionTest(webView, viewWindow); |
|
137 } |
|
138 |
|
139 TEST(WebViewDestruction, DestroyViewWindowWithoutClose) |
|
140 { |
|
141 COMPtr<IWebView> webView; |
|
142 HostWindow window; |
|
143 HWND viewWindow; |
|
144 createAndInitializeWebView(webView, window, viewWindow); |
|
145 |
|
146 DestroyWindow(viewWindow); |
|
147 |
|
148 finishWebViewDestructionTest(webView, viewWindow); |
|
149 } |
|
150 |
|
151 TEST(WebViewDestruction, CloseThenDestroyViewWindow) |
|
152 { |
|
153 COMPtr<IWebView> webView; |
|
154 HostWindow window; |
|
155 HWND viewWindow; |
|
156 createAndInitializeWebView(webView, window, viewWindow); |
|
157 |
|
158 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
159 DestroyWindow(viewWindow); |
|
160 |
|
161 finishWebViewDestructionTest(webView, viewWindow); |
|
162 } |
|
163 |
|
164 TEST(WebViewDestruction, DestroyViewWindowThenClose) |
|
165 { |
|
166 COMPtr<IWebView> webView; |
|
167 HostWindow window; |
|
168 HWND viewWindow; |
|
169 createAndInitializeWebView(webView, window, viewWindow); |
|
170 |
|
171 DestroyWindow(viewWindow); |
|
172 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
173 |
|
174 finishWebViewDestructionTest(webView, viewWindow); |
|
175 } |
|
176 |
|
177 TEST(WebViewDestruction, DestroyHostWindow) |
|
178 { |
|
179 COMPtr<IWebView> webView; |
|
180 HostWindow window; |
|
181 HWND viewWindow; |
|
182 createAndInitializeWebView(webView, window, viewWindow); |
|
183 |
|
184 DestroyWindow(window.window()); |
|
185 |
|
186 finishWebViewDestructionTest(webView, viewWindow); |
|
187 } |
|
188 |
|
189 TEST(WebViewDestruction, DestroyHostWindowThenClose) |
|
190 { |
|
191 COMPtr<IWebView> webView; |
|
192 HostWindow window; |
|
193 HWND viewWindow; |
|
194 createAndInitializeWebView(webView, window, viewWindow); |
|
195 |
|
196 DestroyWindow(window.window()); |
|
197 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
198 |
|
199 finishWebViewDestructionTest(webView, viewWindow); |
|
200 } |
|
201 |
|
202 TEST(WebViewDestruction, CloseThenDestroyHostWindow) |
|
203 { |
|
204 COMPtr<IWebView> webView; |
|
205 HostWindow window; |
|
206 HWND viewWindow; |
|
207 createAndInitializeWebView(webView, window, viewWindow); |
|
208 |
|
209 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
210 DestroyWindow(window.window()); |
|
211 |
|
212 finishWebViewDestructionTest(webView, viewWindow); |
|
213 } |
|
214 |
|
215 // Tests that calling IWebView::mainFrame after calling IWebView::close doesn't crash. <http://webkit.org/b/32868> |
|
216 TEST(WebViewDestruction, MainFrameAfterClose) |
|
217 { |
|
218 COMPtr<IWebView> webView; |
|
219 HostWindow window; |
|
220 HWND viewWindow; |
|
221 createAndInitializeWebView(webView, window, viewWindow); |
|
222 |
|
223 TEST_ASSERT(SUCCEEDED(webView->close())); |
|
224 COMPtr<IWebFrame> mainFrame; |
|
225 TEST_ASSERT(SUCCEEDED(webView->mainFrame(&mainFrame))); |
|
226 |
|
227 finishWebViewDestructionTest(webView, viewWindow); |
|
228 } |
|
229 |
|
230 } // namespace WebKitAPITest |