| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2012 Google 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 are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "TestShell.h" | |
| 33 | |
| 34 #include "DRTDevToolsAgent.h" | |
| 35 #include "DRTDevToolsClient.h" | |
| 36 #include "MockPlatform.h" | |
| 37 #include "MockWebPrerenderingSupport.h" | |
| 38 #include "WebArrayBufferView.h" | |
| 39 #include "WebDataSource.h" | |
| 40 #include "WebDocument.h" | |
| 41 #include "WebElement.h" | |
| 42 #include "WebFrame.h" | |
| 43 #include "WebHistoryItem.h" | |
| 44 #include "WebTestingSupport.h" | |
| 45 #include "WebSettings.h" | |
| 46 #include "WebTestProxy.h" | |
| 47 #include "WebTestRunner.h" | |
| 48 #include "WebView.h" | |
| 49 #include "WebViewHost.h" | |
| 50 #include "skia/ext/platform_canvas.h" | |
| 51 #include "webkit/support/webkit_support.h" | |
| 52 #include "webkit/support/webkit_support_gfx.h" | |
| 53 #include "public/platform/Platform.h" | |
| 54 #include "public/platform/WebCompositorSupport.h" | |
| 55 #include "public/platform/WebPoint.h" | |
| 56 #include "public/platform/WebSize.h" | |
| 57 #include "public/platform/WebString.h" | |
| 58 #include "public/platform/WebThread.h" | |
| 59 #include "public/platform/WebURLRequest.h" | |
| 60 #include "public/platform/WebURLResponse.h" | |
| 61 #include <algorithm> | |
| 62 #include <cctype> | |
| 63 #include <vector> | |
| 64 #include <wtf/MD5.h> | |
| 65 #include <wtf/OwnArrayPtr.h> | |
| 66 | |
| 67 | |
| 68 using namespace WebKit; | |
| 69 using namespace WebTestRunner; | |
| 70 using namespace std; | |
| 71 | |
| 72 // Content area size for newly created windows. | |
| 73 static const int testWindowWidth = 800; | |
| 74 static const int testWindowHeight = 600; | |
| 75 | |
| 76 // The W3C SVG layout tests use a different size than the other layout tests. | |
| 77 static const int SVGTestWindowWidth = 480; | |
| 78 static const int SVGTestWindowHeight = 360; | |
| 79 | |
| 80 static const char layoutTestsPattern[] = "/LayoutTests/"; | |
| 81 static const string::size_type layoutTestsPatternSize = sizeof(layoutTestsPatter
n) - 1; | |
| 82 static const char fileUrlPattern[] = "file:/"; | |
| 83 static const char fileTestPrefix[] = "(file test):"; | |
| 84 static const char dataUrlPattern[] = "data:"; | |
| 85 static const string::size_type dataUrlPatternSize = sizeof(dataUrlPattern) - 1; | |
| 86 | |
| 87 // FIXME: Move this to a common place so that it can be shared with | |
| 88 // WebCore::TransparencyWin::makeLayerOpaque(). | |
| 89 static void makeCanvasOpaque(SkCanvas* canvas) | |
| 90 { | |
| 91 const SkBitmap& bitmap = canvas->getTopDevice()->accessBitmap(true); | |
| 92 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | |
| 93 | |
| 94 SkAutoLockPixels lock(bitmap); | |
| 95 for (int y = 0; y < bitmap.height(); y++) { | |
| 96 uint32_t* row = bitmap.getAddr32(0, y); | |
| 97 for (int x = 0; x < bitmap.width(); x++) | |
| 98 row[x] |= 0xFF000000; // Set alpha bits to 1. | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 TestShell::TestShell() | |
| 103 : m_testIsPending(false) | |
| 104 , m_testIsPreparing(false) | |
| 105 , m_focusedWidget(0) | |
| 106 , m_devTools(0) | |
| 107 , m_dumpPixelsForCurrentTest(false) | |
| 108 , m_allowExternalPages(false) | |
| 109 , m_acceleratedCompositingForVideoEnabled(false) | |
| 110 , m_acceleratedCompositingForFixedPositionEnabled(false) | |
| 111 , m_acceleratedCompositingForOverflowScrollEnabled(false) | |
| 112 , m_acceleratedCompositingForTransitionEnabled(false) | |
| 113 , m_softwareCompositingEnabled(false) | |
| 114 , m_threadedCompositingEnabled(false) | |
| 115 , m_forceCompositingMode(false) | |
| 116 , m_threadedHTMLParser(true) | |
| 117 , m_accelerated2dCanvasEnabled(false) | |
| 118 , m_perTilePaintingEnabled(false) | |
| 119 , m_deferredImageDecodingEnabled(false) | |
| 120 , m_stressOpt(false) | |
| 121 , m_stressDeopt(false) | |
| 122 , m_dumpWhenFinished(true) | |
| 123 , m_isDisplayingModalDialog(false) | |
| 124 { | |
| 125 // 30 second is the same as the value in Mac DRT. | |
| 126 // If we use a value smaller than the timeout value of | |
| 127 // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a | |
| 128 // timed-out DRT process was crashed. | |
| 129 m_timeout = 30 * 1000; | |
| 130 } | |
| 131 | |
| 132 void TestShell::initialize(MockPlatform* platformSupport) | |
| 133 { | |
| 134 m_testInterfaces = adoptPtr(new WebTestInterfaces()); | |
| 135 platformSupport->setInterfaces(m_testInterfaces.get()); | |
| 136 m_devToolsTestInterfaces = adoptPtr(new WebTestInterfaces()); | |
| 137 m_prerenderingSupport = adoptPtr(new MockWebPrerenderingSupport()); | |
| 138 #if !defined(USE_DEFAULT_RENDER_THEME) && (OS(WINDOWS) || OS(DARWIN)) | |
| 139 // Set theme engine. | |
| 140 webkit_support::SetThemeEngine(m_testInterfaces->themeEngine()); | |
| 141 #endif | |
| 142 | |
| 143 if (m_threadedCompositingEnabled) | |
| 144 m_webCompositorThread = adoptPtr(WebKit::Platform::current()->createThre
ad("Compositor")); | |
| 145 webkit_support::SetThreadedCompositorEnabled(m_threadedCompositingEnabled); | |
| 146 | |
| 147 createMainWindow(); | |
| 148 } | |
| 149 | |
| 150 void TestShell::createMainWindow() | |
| 151 { | |
| 152 m_drtDevToolsAgent = adoptPtr(new DRTDevToolsAgent); | |
| 153 m_webViewHost = adoptPtr(createNewWindow(WebURL(), m_drtDevToolsAgent.get(),
m_testInterfaces.get())); | |
| 154 m_webView = m_webViewHost->webView(); | |
| 155 m_testInterfaces->setDelegate(m_webViewHost.get()); | |
| 156 m_testInterfaces->setWebView(m_webView, m_webViewHost->proxy()); | |
| 157 m_drtDevToolsAgent->setWebView(m_webView); | |
| 158 } | |
| 159 | |
| 160 TestShell::~TestShell() | |
| 161 { | |
| 162 if (m_webViewHost) | |
| 163 m_webViewHost->shutdown(); | |
| 164 m_testInterfaces->setDelegate(0); | |
| 165 m_testInterfaces->setWebView(0, 0); | |
| 166 m_devToolsTestInterfaces->setDelegate(0); | |
| 167 m_devToolsTestInterfaces->setWebView(0, 0); | |
| 168 m_drtDevToolsAgent->setWebView(0); | |
| 169 } | |
| 170 | |
| 171 void TestShell::createDRTDevToolsClient(DRTDevToolsAgent* agent) | |
| 172 { | |
| 173 m_drtDevToolsClient = adoptPtr(new DRTDevToolsClient(agent, m_devTools->webV
iew())); | |
| 174 } | |
| 175 | |
| 176 void TestShell::showDevTools() | |
| 177 { | |
| 178 if (!m_devTools) { | |
| 179 WebURL url = webkit_support::GetDevToolsPathAsURL(); | |
| 180 if (!url.isValid()) { | |
| 181 ASSERT(false); | |
| 182 return; | |
| 183 } | |
| 184 m_devTools = createNewWindow(url, 0, m_devToolsTestInterfaces.get()); | |
| 185 m_devTools->webView()->settings()->setMemoryInfoEnabled(true); | |
| 186 m_devTools->proxy()->setLogConsoleOutput(false); | |
| 187 m_devToolsTestInterfaces->setDelegate(m_devTools); | |
| 188 m_devToolsTestInterfaces->setWebView(m_devTools->webView(), m_devTools->
proxy()); | |
| 189 ASSERT(m_devTools); | |
| 190 createDRTDevToolsClient(m_drtDevToolsAgent.get()); | |
| 191 } | |
| 192 m_devTools->show(WebKit::WebNavigationPolicyNewWindow); | |
| 193 } | |
| 194 | |
| 195 void TestShell::closeDevTools() | |
| 196 { | |
| 197 if (m_devTools) { | |
| 198 m_devTools->webView()->settings()->setMemoryInfoEnabled(false); | |
| 199 m_drtDevToolsAgent->reset(); | |
| 200 m_drtDevToolsClient.clear(); | |
| 201 m_devToolsTestInterfaces->setDelegate(0); | |
| 202 m_devToolsTestInterfaces->setWebView(0, 0); | |
| 203 closeWindow(m_devTools); | |
| 204 m_devTools = 0; | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 void TestShell::resetWebSettings(WebView& webView) | |
| 209 { | |
| 210 m_prefs.reset(); | |
| 211 m_prefs.acceleratedCompositingEnabled = true; | |
| 212 m_prefs.acceleratedCompositingForVideoEnabled = m_acceleratedCompositingForV
ideoEnabled; | |
| 213 m_prefs.acceleratedCompositingForFixedPositionEnabled = m_acceleratedComposi
tingForFixedPositionEnabled; | |
| 214 m_prefs.acceleratedCompositingForOverflowScrollEnabled = m_acceleratedCompos
itingForOverflowScrollEnabled; | |
| 215 m_prefs.acceleratedCompositingForTransitionEnabled = m_acceleratedCompositin
gForTransitionEnabled; | |
| 216 m_prefs.forceCompositingMode = m_forceCompositingMode; | |
| 217 m_prefs.accelerated2dCanvasEnabled = m_accelerated2dCanvasEnabled; | |
| 218 m_prefs.perTilePaintingEnabled = m_perTilePaintingEnabled; | |
| 219 m_prefs.deferredImageDecodingEnabled = m_deferredImageDecodingEnabled; | |
| 220 m_prefs.threadedHTMLParser = m_threadedHTMLParser; | |
| 221 m_prefs.applyTo(&webView); | |
| 222 } | |
| 223 | |
| 224 void TestShell::runFileTest(const TestParams& params, bool shouldDumpPixels) | |
| 225 { | |
| 226 ASSERT(params.testUrl.isValid()); | |
| 227 m_dumpPixelsForCurrentTest = shouldDumpPixels; | |
| 228 m_testIsPreparing = true; | |
| 229 m_testInterfaces->setTestIsRunning(true); | |
| 230 m_params = params; | |
| 231 string testUrl = m_params.testUrl.spec(); | |
| 232 m_testInterfaces->configureForTestWithURL(m_params.testUrl, shouldDumpPixels
); | |
| 233 | |
| 234 if (testUrl.find("compositing/") != string::npos || testUrl.find("compositin
g\\") != string::npos) { | |
| 235 if (!m_softwareCompositingEnabled) | |
| 236 m_prefs.accelerated2dCanvasEnabled = true; | |
| 237 m_prefs.acceleratedCompositingForVideoEnabled = true; | |
| 238 m_prefs.mockScrollbarsEnabled = true; | |
| 239 m_prefs.applyTo(m_webView); | |
| 240 } | |
| 241 | |
| 242 if (m_dumpWhenFinished) | |
| 243 m_printer.handleTestHeader(testUrl.c_str()); | |
| 244 loadURL(m_params.testUrl); | |
| 245 | |
| 246 if (m_devTools) | |
| 247 this->setFocus(m_devTools->webView(), true); | |
| 248 | |
| 249 m_testIsPreparing = false; | |
| 250 waitTestFinished(); | |
| 251 } | |
| 252 | |
| 253 static inline bool isSVGTestURL(const WebURL& url) | |
| 254 { | |
| 255 return url.isValid() && string(url.spec()).find("W3C-SVG-1.1") != string::np
os; | |
| 256 } | |
| 257 | |
| 258 void TestShell::resizeWindowForTest(WebViewHost* window, const WebURL& url) | |
| 259 { | |
| 260 int width, height; | |
| 261 if (isSVGTestURL(url)) { | |
| 262 width = SVGTestWindowWidth; | |
| 263 height = SVGTestWindowHeight; | |
| 264 } else { | |
| 265 width = testWindowWidth; | |
| 266 height = testWindowHeight; | |
| 267 } | |
| 268 window->setWindowRect(WebRect(WebViewHost::screenUnavailableBorder, WebViewH
ost::screenUnavailableBorder, width + virtualWindowBorder * 2, height + virtualW
indowBorder * 2)); | |
| 269 } | |
| 270 | |
| 271 void TestShell::resetTestController() | |
| 272 { | |
| 273 resetWebSettings(*webView()); | |
| 274 m_testInterfaces->resetAll(); | |
| 275 m_devToolsTestInterfaces->resetAll(); | |
| 276 m_webViewHost->reset(); | |
| 277 m_drtDevToolsAgent->reset(); | |
| 278 if (m_drtDevToolsClient) | |
| 279 m_drtDevToolsClient->reset(); | |
| 280 webView()->setPageScaleFactor(1, WebPoint(0, 0)); | |
| 281 webView()->enableFixedLayoutMode(false); | |
| 282 webView()->setFixedLayoutSize(WebSize(0, 0)); | |
| 283 webView()->mainFrame()->clearOpener(); | |
| 284 WebTestingSupport::resetInternalsObject(webView()->mainFrame()); | |
| 285 } | |
| 286 | |
| 287 void TestShell::loadURL(const WebURL& url) | |
| 288 { | |
| 289 m_webViewHost->loadURLForFrame(url, string()); | |
| 290 } | |
| 291 | |
| 292 void TestShell::reload() | |
| 293 { | |
| 294 m_webViewHost->navigationController()->reload(); | |
| 295 } | |
| 296 | |
| 297 void TestShell::goToOffset(int offset) | |
| 298 { | |
| 299 m_webViewHost->navigationController()->goToOffset(offset); | |
| 300 } | |
| 301 | |
| 302 int TestShell::navigationEntryCount() const | |
| 303 { | |
| 304 return m_webViewHost->navigationController()->entryCount(); | |
| 305 } | |
| 306 | |
| 307 void TestShell::callJSGC() | |
| 308 { | |
| 309 m_webView->mainFrame()->collectGarbage(); | |
| 310 } | |
| 311 | |
| 312 void TestShell::setFocus(WebWidget* widget, bool enable) | |
| 313 { | |
| 314 // Simulate the effects of InteractiveSetFocus(), which includes calling | |
| 315 // both setFocus() and setIsActive(). | |
| 316 if (enable) { | |
| 317 if (m_focusedWidget != widget) { | |
| 318 if (m_focusedWidget) | |
| 319 m_focusedWidget->setFocus(false); | |
| 320 webView()->setIsActive(enable); | |
| 321 widget->setFocus(enable); | |
| 322 m_focusedWidget = widget; | |
| 323 } | |
| 324 } else { | |
| 325 if (m_focusedWidget == widget) { | |
| 326 widget->setFocus(enable); | |
| 327 webView()->setIsActive(enable); | |
| 328 m_focusedWidget = 0; | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 | |
| 333 void TestShell::testFinished(WebViewHost* host) | |
| 334 { | |
| 335 if (host == m_devTools) | |
| 336 return; | |
| 337 | |
| 338 if (!m_testIsPending) | |
| 339 return; | |
| 340 m_testIsPending = false; | |
| 341 m_testInterfaces->setTestIsRunning(false); | |
| 342 if (m_dumpWhenFinished) | |
| 343 dump(); | |
| 344 webkit_support::QuitMessageLoop(); | |
| 345 } | |
| 346 | |
| 347 void TestShell::testTimedOut() | |
| 348 { | |
| 349 m_printer.handleTimedOut(); | |
| 350 testFinished(webViewHost()); | |
| 351 } | |
| 352 | |
| 353 void TestShell::dump() | |
| 354 { | |
| 355 // Dump the requested representation. | |
| 356 WebFrame* frame = m_webView->mainFrame(); | |
| 357 if (!frame) | |
| 358 return; | |
| 359 bool shouldDumpAsAudio = m_testInterfaces->testRunner()->shouldDumpAsAudio()
; | |
| 360 bool shouldGeneratePixelResults = m_testInterfaces->testRunner()->shouldGene
ratePixelResults(); | |
| 361 bool dumpedAnything = false; | |
| 362 | |
| 363 if (shouldDumpAsAudio) { | |
| 364 const WebKit::WebArrayBufferView* webArrayBufferView = m_testInterfaces-
>testRunner()->audioData(); | |
| 365 m_printer.handleAudio(webArrayBufferView->baseAddress(), webArrayBufferV
iew->byteLength()); | |
| 366 m_printer.handleAudioFooter(); | |
| 367 m_printer.handleTestFooter(true); | |
| 368 | |
| 369 fflush(stdout); | |
| 370 fflush(stderr); | |
| 371 return; | |
| 372 } | |
| 373 | |
| 374 if (m_params.dumpTree) { | |
| 375 dumpedAnything = true; | |
| 376 m_printer.handleTextHeader(); | |
| 377 string dataUtf8 = m_webViewHost->proxy()->captureTree(m_params.debugRend
erTree); | |
| 378 if (fwrite(dataUtf8.c_str(), 1, dataUtf8.size(), stdout) != dataUtf8.siz
e()) | |
| 379 FATAL("Short write to stdout, disk full?\n"); | |
| 380 } | |
| 381 if (dumpedAnything && m_params.printSeparators) | |
| 382 m_printer.handleTextFooter(); | |
| 383 | |
| 384 if (m_dumpPixelsForCurrentTest && shouldGeneratePixelResults) { | |
| 385 // Image output: we write the image data to the file given on the | |
| 386 // command line (for the dump pixels argument), and the MD5 sum to | |
| 387 // stdout. | |
| 388 dumpedAnything = true; | |
| 389 dumpImage(m_webViewHost->proxy()->capturePixels()); | |
| 390 } | |
| 391 m_printer.handleTestFooter(dumpedAnything); | |
| 392 fflush(stdout); | |
| 393 fflush(stderr); | |
| 394 } | |
| 395 | |
| 396 void TestShell::dumpImage(SkCanvas* canvas) const | |
| 397 { | |
| 398 // Fix the alpha. The expected PNGs on Mac have an alpha channel, so we want | |
| 399 // to keep it. On Windows, the alpha channel is wrong since text/form contro
l | |
| 400 // drawing may have erased it in a few places. So on Windows we force it to | |
| 401 // opaque and also don't write the alpha channel for the reference. Linux | |
| 402 // doesn't have the wrong alpha like Windows, but we match Windows. | |
| 403 #if OS(DARWIN) | |
| 404 bool discardTransparency = false; | |
| 405 #else | |
| 406 bool discardTransparency = true; | |
| 407 makeCanvasOpaque(canvas); | |
| 408 #endif | |
| 409 | |
| 410 const SkBitmap& sourceBitmap = canvas->getTopDevice()->accessBitmap(false); | |
| 411 SkAutoLockPixels sourceBitmapLock(sourceBitmap); | |
| 412 | |
| 413 // Compute MD5 sum. | |
| 414 MD5 digester; | |
| 415 Vector<uint8_t, 16> digestValue; | |
| 416 #if OS(ANDROID) | |
| 417 // On Android, pixel layout is RGBA (see third_party/skia/include/core/SkCol
orPriv.h); | |
| 418 // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h)
. | |
| 419 // To match the checksum of other Chrome platforms, we need to reorder the l
ayout of pixels. | |
| 420 // NOTE: The following code assumes we use SkBitmap::kARGB_8888_Config, | |
| 421 // which has been checked in device.makeOpaque() (see above). | |
| 422 const uint8_t* rawPixels = reinterpret_cast<const uint8_t*>(sourceBitmap.get
Pixels()); | |
| 423 size_t bitmapSize = sourceBitmap.getSize(); | |
| 424 OwnArrayPtr<uint8_t> reorderedPixels = adoptArrayPtr(new uint8_t[bitmapSize]
); | |
| 425 for (size_t i = 0; i < bitmapSize; i += 4) { | |
| 426 reorderedPixels[i] = rawPixels[i + 2]; // R | |
| 427 reorderedPixels[i + 1] = rawPixels[i + 1]; // G | |
| 428 reorderedPixels[i + 2] = rawPixels[i]; // B | |
| 429 reorderedPixels[i + 3] = rawPixels[i + 3]; // A | |
| 430 } | |
| 431 digester.addBytes(reorderedPixels.get(), bitmapSize); | |
| 432 reorderedPixels.clear(); | |
| 433 #else | |
| 434 digester.addBytes(reinterpret_cast<const uint8_t*>(sourceBitmap.getPixels())
, sourceBitmap.getSize()); | |
| 435 #endif | |
| 436 digester.checksum(digestValue); | |
| 437 string md5hash; | |
| 438 md5hash.reserve(16 * 2); | |
| 439 for (unsigned i = 0; i < 16; ++i) { | |
| 440 char hex[3]; | |
| 441 // Use "x", not "X". The string must be lowercased. | |
| 442 sprintf(hex, "%02x", digestValue[i]); | |
| 443 md5hash.append(hex); | |
| 444 } | |
| 445 | |
| 446 // Only encode and dump the png if the hashes don't match. Encoding the | |
| 447 // image is really expensive. | |
| 448 if (md5hash.compare(m_params.pixelHash)) { | |
| 449 std::vector<unsigned char> png; | |
| 450 #if OS(ANDROID) | |
| 451 webkit_support::EncodeRGBAPNGWithChecksum(reinterpret_cast<const unsigne
d char*>(sourceBitmap.getPixels()), sourceBitmap.width(), | |
| 452 sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), di
scardTransparency, md5hash, &png); | |
| 453 #else | |
| 454 webkit_support::EncodeBGRAPNGWithChecksum(reinterpret_cast<const unsigne
d char*>(sourceBitmap.getPixels()), sourceBitmap.width(), | |
| 455 sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), di
scardTransparency, md5hash, &png); | |
| 456 #endif | |
| 457 | |
| 458 m_printer.handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[
0], png.size()); | |
| 459 } else | |
| 460 m_printer.handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0)
; | |
| 461 } | |
| 462 | |
| 463 void TestShell::bindJSObjectsToWindow(WebFrame* frame) | |
| 464 { | |
| 465 WebTestingSupport::injectInternalsObject(frame); | |
| 466 if (m_devTools && m_devTools->webView() == frame->view()) | |
| 467 m_devToolsTestInterfaces->bindTo(frame); | |
| 468 else | |
| 469 m_testInterfaces->bindTo(frame); | |
| 470 } | |
| 471 | |
| 472 WebViewHost* TestShell::createNewWindow(const WebKit::WebURL& url) | |
| 473 { | |
| 474 return createNewWindow(url, 0, m_testInterfaces.get()); | |
| 475 } | |
| 476 | |
| 477 WebViewHost* TestShell::createNewWindow(const WebKit::WebURL& url, DRTDevToolsAg
ent* devToolsAgent, WebTestInterfaces *testInterfaces) | |
| 478 { | |
| 479 WebTestProxy<WebViewHost, TestShell*>* host = new WebTestProxy<WebViewHost,
TestShell*>(this); | |
| 480 host->setInterfaces(testInterfaces); | |
| 481 if (m_webViewHost) | |
| 482 host->setDelegate(m_webViewHost.get()); | |
| 483 else | |
| 484 host->setDelegate(host); | |
| 485 host->setProxy(host); | |
| 486 WebView* view = WebView::create(host); | |
| 487 view->setPermissionClient(testInterfaces->testRunner()->webPermissions()); | |
| 488 view->setDevToolsAgentClient(devToolsAgent); | |
| 489 host->setWebWidget(view); | |
| 490 m_prefs.applyTo(view); | |
| 491 view->initializeMainFrame(host); | |
| 492 m_windowList.append(host); | |
| 493 host->loadURLForFrame(url, string()); | |
| 494 return host; | |
| 495 } | |
| 496 | |
| 497 void TestShell::closeWindow(WebViewHost* window) | |
| 498 { | |
| 499 size_t i = m_windowList.find(window); | |
| 500 if (i == notFound) { | |
| 501 ASSERT_NOT_REACHED(); | |
| 502 return; | |
| 503 } | |
| 504 m_windowList.remove(i); | |
| 505 WebWidget* focusedWidget = m_focusedWidget; | |
| 506 if (window->webWidget() == m_focusedWidget) | |
| 507 focusedWidget = 0; | |
| 508 | |
| 509 window->shutdown(); | |
| 510 delete window; | |
| 511 // We set the focused widget after deleting the web view host because it | |
| 512 // can change the focus. | |
| 513 m_focusedWidget = focusedWidget; | |
| 514 if (m_focusedWidget) { | |
| 515 webView()->setIsActive(true); | |
| 516 m_focusedWidget->setFocus(true); | |
| 517 } | |
| 518 } | |
| 519 | |
| 520 void TestShell::closeRemainingWindows() | |
| 521 { | |
| 522 // Just close devTools window manually because we have custom deinitializati
on code for it. | |
| 523 closeDevTools(); | |
| 524 | |
| 525 // Iterate through the window list and close everything except the main | |
| 526 // window. We don't want to delete elements as we're iterating, so we copy | |
| 527 // to a temp vector first. | |
| 528 Vector<WebViewHost*> windowsToDelete; | |
| 529 for (unsigned i = 0; i < m_windowList.size(); ++i) { | |
| 530 if (m_windowList[i] != webViewHost()) | |
| 531 windowsToDelete.append(m_windowList[i]); | |
| 532 } | |
| 533 ASSERT(windowsToDelete.size() + 1 == m_windowList.size()); | |
| 534 for (unsigned i = 0; i < windowsToDelete.size(); ++i) | |
| 535 closeWindow(windowsToDelete[i]); | |
| 536 ASSERT(m_windowList.size() == 1); | |
| 537 } | |
| 538 | |
| 539 int TestShell::windowCount() | |
| 540 { | |
| 541 return m_windowList.size(); | |
| 542 } | |
| 543 | |
| 544 void TestShell::captureHistoryForWindow(size_t windowIndex, WebVector<WebHistory
Item>* history, size_t* currentEntryIndex) | |
| 545 { | |
| 546 ASSERT(history); | |
| 547 ASSERT(currentEntryIndex); | |
| 548 if (windowIndex >= m_windowList.size()) | |
| 549 return; | |
| 550 TestNavigationController& navigationController = *m_windowList[windowIndex]-
>navigationController(); | |
| 551 size_t entryCount = navigationController.entryCount(); | |
| 552 WebVector<WebHistoryItem> result(entryCount); | |
| 553 *currentEntryIndex = navigationController.lastCommittedEntryIndex(); | |
| 554 for (size_t index = 0; index < entryCount; ++index) { | |
| 555 WebHistoryItem historyItem = navigationController.entryAtIndex(index)->c
ontentState(); | |
| 556 if (historyItem.isNull()) { | |
| 557 historyItem.initialize(); | |
| 558 historyItem.setURLString(navigationController.entryAtIndex(index)->U
RL().spec().utf16()); | |
| 559 } | |
| 560 result[index] = historyItem; | |
| 561 } | |
| 562 history->swap(result); | |
| 563 } | |
| OLD | NEW |