Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/shell/renderer/test_runner/web_test_proxy.h" | 5 #include "content/shell/renderer/test_runner/web_test_proxy.h" |
| 6 | 6 |
| 7 #include <cctype> | 7 #include <cctype> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 if (m_speechRecognizer.get()) m_speechRecognizer->setDelegate(delegate); | 305 if (m_speechRecognizer.get()) m_speechRecognizer->setDelegate(delegate); |
| 306 } | 306 } |
| 307 | 307 |
| 308 WebView* WebTestProxyBase::GetWebView() const { | 308 WebView* WebTestProxyBase::GetWebView() const { |
| 309 DCHECK(web_widget_); | 309 DCHECK(web_widget_); |
| 310 // TestRunner does not support popup widgets. So |web_widget|_ is always a | 310 // TestRunner does not support popup widgets. So |web_widget|_ is always a |
| 311 // WebView. | 311 // WebView. |
| 312 return static_cast<WebView*>(web_widget_); | 312 return static_cast<WebView*>(web_widget_); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void WebTestProxyBase::DidForceResize() { | |
| 316 InvalidateAll(); | |
| 317 DiscardBackingStore(); | |
| 318 } | |
| 319 | |
| 320 void WebTestProxyBase::Reset() { | 315 void WebTestProxyBase::Reset() { |
| 321 paint_rect_ = WebRect(); | |
| 322 canvas_.reset(); | |
| 323 is_painting_ = false; | |
| 324 animate_scheduled_ = false; | 316 animate_scheduled_ = false; |
| 325 resource_identifier_map_.clear(); | 317 resource_identifier_map_.clear(); |
| 326 log_console_output_ = true; | 318 log_console_output_ = true; |
| 327 if (m_midiClient.get()) m_midiClient->resetMock(); | 319 if (m_midiClient.get()) m_midiClient->resetMock(); |
| 328 } | 320 } |
| 329 | 321 |
| 330 WebSpellCheckClient* WebTestProxyBase::GetSpellCheckClient() const { | 322 WebSpellCheckClient* WebTestProxyBase::GetSpellCheckClient() const { |
| 331 return spellcheck_.get(); | 323 return spellcheck_.get(); |
| 332 } | 324 } |
| 333 | 325 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 bitmap.info().fWidth, "y", bitmap.info().fHeight); | 413 bitmap.info().fWidth, "y", bitmap.info().fHeight); |
| 422 SkCanvas canvas(bitmap); | 414 SkCanvas canvas(bitmap); |
| 423 DrawSelectionRect(&canvas); | 415 DrawSelectionRect(&canvas); |
| 424 DCHECK(!composite_and_readback_callbacks_.empty()); | 416 DCHECK(!composite_and_readback_callbacks_.empty()); |
| 425 composite_and_readback_callbacks_.front().Run(bitmap); | 417 composite_and_readback_callbacks_.front().Run(bitmap); |
| 426 composite_and_readback_callbacks_.pop_front(); | 418 composite_and_readback_callbacks_.pop_front(); |
| 427 } | 419 } |
| 428 | 420 |
| 429 void WebTestProxyBase::CapturePixelsForPrinting( | 421 void WebTestProxyBase::CapturePixelsForPrinting( |
| 430 const base::Callback<void(const SkBitmap&)>& callback) { | 422 const base::Callback<void(const SkBitmap&)>& callback) { |
| 431 // TODO(enne): get rid of stateful canvas(). | |
| 432 web_widget_->layout(); | 423 web_widget_->layout(); |
| 433 PaintPagesWithBoundaries(); | 424 |
| 434 DrawSelectionRect(GetCanvas()); | 425 WebSize pageSizeInPixels = web_widget_->size(); |
| 435 SkBaseDevice* device = skia::GetTopDevice(*GetCanvas()); | 426 WebFrame* webFrame = GetWebView()->mainFrame(); |
| 427 | |
| 428 int pageCount = webFrame->printBegin(pageSizeInPixels); | |
|
danakj
2014/05/15 14:34:33
page_count, etc. if is_opaque is going to be chrom
enne (OOO)
2014/05/15 17:10:33
How about I just fix up this whole file afterwards
danakj
2014/05/15 17:11:02
Yes, please. :)
| |
| 429 int totalHeight = pageCount * (pageSizeInPixels.height + 1) - 1; | |
| 430 | |
| 431 bool is_opaque = false; | |
| 432 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::TryCreateBitmapCanvas( | |
| 433 pageSizeInPixels.width, totalHeight, is_opaque))); | |
| 434 if (canvas.get()) | |
|
danakj
2014/05/15 14:34:33
nit: no .get() needed
enne (OOO)
2014/05/15 17:10:33
Done.
| |
| 435 webFrame->printPagesWithBoundaries(canvas.get(), pageSizeInPixels); | |
| 436 webFrame->printEnd(); | |
| 437 | |
| 438 DrawSelectionRect(canvas.get()); | |
| 439 SkBaseDevice* device = skia::GetTopDevice(*canvas.get()); | |
|
danakj
2014/05/15 14:34:33
nit: no .get() needed
enne (OOO)
2014/05/15 17:10:33
Done.
| |
| 436 const SkBitmap& bitmap = device->accessBitmap(false); | 440 const SkBitmap& bitmap = device->accessBitmap(false); |
| 437 callback.Run(bitmap); | 441 callback.Run(bitmap); |
| 438 } | 442 } |
| 439 | 443 |
| 440 void WebTestProxyBase::CapturePixelsAsync( | 444 void WebTestProxyBase::CapturePixelsAsync( |
| 441 const base::Callback<void(const SkBitmap&)>& callback) { | 445 const base::Callback<void(const SkBitmap&)>& callback) { |
| 442 TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync"); | 446 TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync"); |
| 443 | 447 |
| 444 DCHECK(web_widget_->isAcceleratedCompositingActive()); | 448 DCHECK(web_widget_->isAcceleratedCompositingActive()); |
| 445 DCHECK(!callback.is_null()); | 449 DCHECK(!callback.is_null()); |
| 446 | 450 |
| 447 if (test_interfaces_->testRunner()->isPrinting()) { | 451 if (test_interfaces_->testRunner()->isPrinting()) { |
| 448 base::MessageLoopProxy::current()->PostTask( | 452 base::MessageLoopProxy::current()->PostTask( |
| 449 FROM_HERE, base::Bind(&WebTestProxyBase::CapturePixelsForPrinting, | 453 FROM_HERE, base::Bind(&WebTestProxyBase::CapturePixelsForPrinting, |
| 450 base::Unretained(this), callback)); | 454 base::Unretained(this), callback)); |
| 451 return; | 455 return; |
| 452 } | 456 } |
| 453 | 457 |
| 454 composite_and_readback_callbacks_.push_back(callback); | 458 composite_and_readback_callbacks_.push_back(callback); |
| 455 web_widget_->compositeAndReadbackAsync(this); | 459 web_widget_->compositeAndReadbackAsync(this); |
| 456 } | 460 } |
| 457 | 461 |
| 458 void WebTestProxyBase::SetLogConsoleOutput(bool enabled) { | 462 void WebTestProxyBase::SetLogConsoleOutput(bool enabled) { |
| 459 log_console_output_ = enabled; | 463 log_console_output_ = enabled; |
| 460 } | 464 } |
| 461 | 465 |
| 462 void WebTestProxyBase::PaintPagesWithBoundaries() { | |
| 463 DCHECK(!is_painting_); | |
| 464 DCHECK(GetCanvas()); | |
| 465 is_painting_ = true; | |
| 466 | |
| 467 WebSize pageSizeInPixels = web_widget_->size(); | |
| 468 WebFrame* webFrame = GetWebView()->mainFrame(); | |
| 469 | |
| 470 int pageCount = webFrame->printBegin(pageSizeInPixels); | |
| 471 int totalHeight = pageCount * (pageSizeInPixels.height + 1) - 1; | |
| 472 | |
| 473 SkCanvas* testCanvas = | |
| 474 skia::TryCreateBitmapCanvas(pageSizeInPixels.width, totalHeight, false); | |
| 475 if (testCanvas) { | |
| 476 DiscardBackingStore(); | |
| 477 canvas_.reset(testCanvas); | |
| 478 } else { | |
| 479 webFrame->printEnd(); | |
| 480 return; | |
| 481 } | |
| 482 | |
| 483 webFrame->printPagesWithBoundaries(GetCanvas(), pageSizeInPixels); | |
| 484 webFrame->printEnd(); | |
| 485 | |
| 486 is_painting_ = false; | |
| 487 } | |
| 488 | |
| 489 SkCanvas* WebTestProxyBase::GetCanvas() { | |
| 490 if (canvas_.get()) return canvas_.get(); | |
| 491 WebSize widgetSize = web_widget_->size(); | |
| 492 float deviceScaleFactor = GetWebView()->deviceScaleFactor(); | |
| 493 int scaledWidth = static_cast<int>( | |
| 494 ceil(static_cast<float>(widgetSize.width) * deviceScaleFactor)); | |
| 495 int scaledHeight = static_cast<int>( | |
| 496 ceil(static_cast<float>(widgetSize.height) * deviceScaleFactor)); | |
| 497 // We're allocating the canvas to be non-opaque (third parameter), so we | |
| 498 // don't end up with uninitialized memory if a layout test doesn't damage | |
| 499 // the entire view. | |
| 500 canvas_.reset(skia::CreateBitmapCanvas(scaledWidth, scaledHeight, false)); | |
| 501 return canvas_.get(); | |
| 502 } | |
| 503 | |
| 504 void WebTestProxyBase::DidDisplayAsync(const base::Closure& callback, | 466 void WebTestProxyBase::DidDisplayAsync(const base::Closure& callback, |
| 505 const SkBitmap& bitmap) { | 467 const SkBitmap& bitmap) { |
| 506 // Verify we actually composited. | 468 // Verify we actually composited. |
| 507 CHECK_NE(0, bitmap.info().fWidth); | 469 CHECK_NE(0, bitmap.info().fWidth); |
| 508 CHECK_NE(0, bitmap.info().fHeight); | 470 CHECK_NE(0, bitmap.info().fHeight); |
| 509 if (!callback.is_null()) callback.Run(); | 471 if (!callback.is_null()) callback.Run(); |
| 510 } | 472 } |
| 511 | 473 |
| 512 void WebTestProxyBase::DisplayAsyncThen(const base::Closure& callback) { | 474 void WebTestProxyBase::DisplayAsyncThen(const base::Closure& callback) { |
| 513 TRACE_EVENT0("shell", "WebTestProxyBase::DisplayAsyncThen"); | 475 TRACE_EVENT0("shell", "WebTestProxyBase::DisplayAsyncThen"); |
| 514 | 476 |
| 515 CHECK(web_widget_->isAcceleratedCompositingActive()); | 477 CHECK(web_widget_->isAcceleratedCompositingActive()); |
| 516 CapturePixelsAsync(base::Bind(&WebTestProxyBase::DidDisplayAsync, | 478 CapturePixelsAsync(base::Bind(&WebTestProxyBase::DidDisplayAsync, |
| 517 base::Unretained(this), callback)); | 479 base::Unretained(this), callback)); |
| 518 } | 480 } |
| 519 | 481 |
| 520 void WebTestProxyBase::DiscardBackingStore() { canvas_.reset(); } | |
| 521 | |
| 522 WebMIDIClientMock* WebTestProxyBase::GetMIDIClientMock() { | 482 WebMIDIClientMock* WebTestProxyBase::GetMIDIClientMock() { |
| 523 if (!m_midiClient.get()) m_midiClient.reset(new WebMIDIClientMock); | 483 if (!m_midiClient.get()) m_midiClient.reset(new WebMIDIClientMock); |
| 524 return m_midiClient.get(); | 484 return m_midiClient.get(); |
| 525 } | 485 } |
| 526 | 486 |
| 527 MockWebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizerMock() { | 487 MockWebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizerMock() { |
| 528 if (!m_speechRecognizer.get()) { | 488 if (!m_speechRecognizer.get()) { |
| 529 m_speechRecognizer.reset(new MockWebSpeechRecognizer()); | 489 m_speechRecognizer.reset(new MockWebSpeechRecognizer()); |
| 530 m_speechRecognizer->setDelegate(delegate_); | 490 m_speechRecognizer->setDelegate(delegate_); |
| 531 } | 491 } |
| 532 return m_speechRecognizer.get(); | 492 return m_speechRecognizer.get(); |
| 533 } | 493 } |
| 534 | 494 |
| 535 void WebTestProxyBase::DidInvalidateRect(const WebRect& rect) { | 495 void WebTestProxyBase::ScheduleComposite() { |
|
danakj
2014/05/15 14:34:33
If this does nothing can it go away?
| |
| 536 // paint_rect_ = paint_rect_ U rect | |
| 537 if (rect.isEmpty()) return; | |
| 538 if (paint_rect_.isEmpty()) { | |
| 539 paint_rect_ = rect; | |
| 540 return; | |
| 541 } | |
| 542 int left = min(paint_rect_.x, rect.x); | |
| 543 int top = min(paint_rect_.y, rect.y); | |
| 544 int right = max(paint_rect_.x + paint_rect_.width, rect.x + rect.width); | |
| 545 int bottom = max(paint_rect_.y + paint_rect_.height, rect.y + rect.height); | |
| 546 paint_rect_ = WebRect(left, top, right - left, bottom - top); | |
| 547 } | 496 } |
| 548 | 497 |
| 549 void WebTestProxyBase::DidScrollRect(int, int, const WebRect& clipRect) { | |
| 550 DidInvalidateRect(clipRect); | |
| 551 } | |
| 552 | |
| 553 void WebTestProxyBase::InvalidateAll() { | |
| 554 paint_rect_ = WebRect(0, 0, INT_MAX, INT_MAX); | |
| 555 } | |
| 556 | |
| 557 void WebTestProxyBase::ScheduleComposite() { InvalidateAll(); } | |
| 558 | |
| 559 void WebTestProxyBase::ScheduleAnimation() { | 498 void WebTestProxyBase::ScheduleAnimation() { |
| 560 if (!test_interfaces_->testRunner()->TestIsRunning()) return; | 499 if (!test_interfaces_->testRunner()->TestIsRunning()) return; |
| 561 | 500 |
| 562 if (!animate_scheduled_) { | 501 if (!animate_scheduled_) { |
| 563 animate_scheduled_ = true; | 502 animate_scheduled_ = true; |
| 564 delegate_->postDelayedTask( | 503 delegate_->postDelayedTask( |
| 565 new HostMethodTask(this, &WebTestProxyBase::AnimateNow), 1); | 504 new HostMethodTask(this, &WebTestProxyBase::AnimateNow), 1); |
| 566 } | 505 } |
| 567 } | 506 } |
| 568 | 507 |
| 569 void WebTestProxyBase::AnimateNow() { | 508 void WebTestProxyBase::AnimateNow() { |
| 570 if (animate_scheduled_) { | 509 if (animate_scheduled_) { |
| 571 animate_scheduled_ = false; | 510 animate_scheduled_ = false; |
| 572 web_widget_->animate(0.0); | 511 web_widget_->animate(0.0); |
| 573 web_widget_->layout(); | 512 web_widget_->layout(); |
| 574 } | 513 } |
| 575 } | 514 } |
| 576 | 515 |
| 577 bool WebTestProxyBase::IsCompositorFramePending() const { | |
| 578 return animate_scheduled_ || !paint_rect_.isEmpty(); | |
| 579 } | |
| 580 | |
| 581 void WebTestProxyBase::Show(WebNavigationPolicy) { InvalidateAll(); } | |
| 582 | |
| 583 void WebTestProxyBase::SetWindowRect(const WebRect& rect) { | |
| 584 InvalidateAll(); | |
| 585 DiscardBackingStore(); | |
| 586 } | |
| 587 | |
| 588 void WebTestProxyBase::DidAutoResize(const WebSize&) { InvalidateAll(); } | |
| 589 | |
| 590 void WebTestProxyBase::PostAccessibilityEvent(const blink::WebAXObject& obj, | 516 void WebTestProxyBase::PostAccessibilityEvent(const blink::WebAXObject& obj, |
| 591 blink::WebAXEvent event) { | 517 blink::WebAXEvent event) { |
| 592 // Only hook the accessibility events occured during the test run. | 518 // Only hook the accessibility events occured during the test run. |
| 593 // This check prevents false positives in WebLeakDetector. | 519 // This check prevents false positives in WebLeakDetector. |
| 594 // The pending tasks in browser/renderer message queue may trigger | 520 // The pending tasks in browser/renderer message queue may trigger |
| 595 // accessibility events, | 521 // accessibility events, |
| 596 // and AccessibilityController will hold on to their target nodes if we don't | 522 // and AccessibilityController will hold on to their target nodes if we don't |
| 597 // ignore them here. | 523 // ignore them here. |
| 598 if (!test_interfaces_->testRunner()->TestIsRunning()) return; | 524 if (!test_interfaces_->testRunner()->TestIsRunning()) return; |
| 599 | 525 |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1184 } | 1110 } |
| 1185 } | 1111 } |
| 1186 | 1112 |
| 1187 void WebTestProxyBase::ResetInputMethod() { | 1113 void WebTestProxyBase::ResetInputMethod() { |
| 1188 // If a composition text exists, then we need to let the browser process | 1114 // If a composition text exists, then we need to let the browser process |
| 1189 // to cancel the input method's ongoing composition session. | 1115 // to cancel the input method's ongoing composition session. |
| 1190 if (web_widget_) web_widget_->confirmComposition(); | 1116 if (web_widget_) web_widget_->confirmComposition(); |
| 1191 } | 1117 } |
| 1192 | 1118 |
| 1193 } // namespace content | 1119 } // namespace content |
| OLD | NEW |