| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 package org.chromium.android_webview.test; | 5 package org.chromium.android_webview.test; |
| 6 | 6 |
| 7 import android.graphics.Bitmap; | 7 import android.graphics.Bitmap; |
| 8 import android.graphics.Color; | 8 import android.graphics.Color; |
| 9 import android.graphics.Rect; | 9 import android.graphics.Rect; |
| 10 import android.test.suitebuilder.annotation.SmallTest; | 10 import android.test.suitebuilder.annotation.SmallTest; |
| 11 import android.util.Base64; | 11 import android.util.Base64; |
| 12 import android.view.View; | |
| 13 import android.webkit.WebChromeClient; | |
| 14 | 12 |
| 15 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; | 13 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; |
| 16 | 14 |
| 17 import org.chromium.android_webview.AwContents; | 15 import org.chromium.android_webview.AwContents; |
| 18 import org.chromium.android_webview.AwContents.VisualStateCallback; | 16 import org.chromium.android_webview.AwContents.VisualStateCallback; |
| 17 import org.chromium.android_webview.AwContentsClient; |
| 19 import org.chromium.android_webview.AwWebResourceResponse; | 18 import org.chromium.android_webview.AwWebResourceResponse; |
| 20 import org.chromium.android_webview.test.util.CommonResources; | 19 import org.chromium.android_webview.test.util.CommonResources; |
| 21 import org.chromium.android_webview.test.util.GraphicsTestUtils; | 20 import org.chromium.android_webview.test.util.GraphicsTestUtils; |
| 22 import org.chromium.android_webview.test.util.JavascriptEventObserver; | 21 import org.chromium.android_webview.test.util.JavascriptEventObserver; |
| 23 import org.chromium.base.ThreadUtils; | 22 import org.chromium.base.ThreadUtils; |
| 24 import org.chromium.base.test.util.Feature; | 23 import org.chromium.base.test.util.Feature; |
| 25 import org.chromium.content.browser.ContentViewCore; | 24 import org.chromium.content.browser.ContentViewCore; |
| 26 import org.chromium.content.browser.test.util.CallbackHelper; | 25 import org.chromium.content.browser.test.util.CallbackHelper; |
| 27 import org.chromium.content.browser.test.util.DOMUtils; | 26 import org.chromium.content.browser.test.util.DOMUtils; |
| 28 import org.chromium.content_public.browser.LoadUrlParams; | 27 import org.chromium.content_public.browser.LoadUrlParams; |
| 29 | 28 |
| 30 import java.io.ByteArrayInputStream; | 29 import java.io.ByteArrayInputStream; |
| 31 import java.io.FilterInputStream; | 30 import java.io.FilterInputStream; |
| 32 import java.io.IOException; | 31 import java.io.IOException; |
| 33 import java.io.InputStream; | 32 import java.io.InputStream; |
| 34 | 33 |
| 34 import java.util.concurrent.Callable; |
| 35 import java.util.concurrent.CountDownLatch; | 35 import java.util.concurrent.CountDownLatch; |
| 36 import java.util.concurrent.TimeUnit; | 36 import java.util.concurrent.TimeUnit; |
| 37 import java.util.concurrent.atomic.AtomicReference; | 37 import java.util.concurrent.atomic.AtomicReference; |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * Visual state related tests. | 40 * Visual state related tests. |
| 41 */ | 41 */ |
| 42 public class VisualStateTest extends AwTestBase { | 42 public class VisualStateTest extends AwTestBase { |
| 43 private static final String WAIT_FOR_JS_TEST_URL = | 43 private static final String WAIT_FOR_JS_TEST_URL = |
| 44 "file:///android_asset/visual_state_waits_for_js_test.html"; | 44 "file:///android_asset/visual_state_waits_for_js_test.html"; |
| 45 private static final String WAIT_FOR_JS_DETACHED_TEST_URL = |
| 46 "file:///android_asset/visual_state_waits_for_js_detached_test.html"
; |
| 45 private static final String ON_PAGE_COMMIT_VISIBLE_TEST_URL = | 47 private static final String ON_PAGE_COMMIT_VISIBLE_TEST_URL = |
| 46 "file:///android_asset/visual_state_on_page_commit_visible_test.html
"; | 48 "file:///android_asset/visual_state_on_page_commit_visible_test.html
"; |
| 47 private static final String FULLSCREEN_TEST_URL = | 49 private static final String FULLSCREEN_TEST_URL = |
| 48 "file:///android_asset/visual_state_during_fullscreen_test.html"; | 50 "file:///android_asset/visual_state_during_fullscreen_test.html"; |
| 49 private static final String UPDATE_COLOR_CONTROL_ID = "updateColorControl"; | 51 private static final String UPDATE_COLOR_CONTROL_ID = "updateColorControl"; |
| 50 private static final String ENTER_FULLSCREEN_CONTROL_ID = "enterFullscreenCo
ntrol"; | 52 private static final String ENTER_FULLSCREEN_CONTROL_ID = "enterFullscreenCo
ntrol"; |
| 51 | 53 |
| 52 private TestAwContentsClient mContentsClient = new TestAwContentsClient(); | 54 private TestAwContentsClient mContentsClient = new TestAwContentsClient(); |
| 53 | 55 |
| 54 private static class DelayedInputStream extends FilterInputStream { | 56 private static class DelayedInputStream extends FilterInputStream { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 assertEquals(Color.RED, redScreenshot.getPixel(50, 50)); | 398 assertEquals(Color.RED, redScreenshot.getPixel(50, 50)); |
| 397 testFinishedSignal.countDown(); | 399 testFinishedSignal.countDown(); |
| 398 } | 400 } |
| 399 }); | 401 }); |
| 400 } | 402 } |
| 401 }); | 403 }); |
| 402 | 404 |
| 403 assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit
.MILLISECONDS)); | 405 assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit
.MILLISECONDS)); |
| 404 } | 406 } |
| 405 | 407 |
| 408 private AwTestContainerView createDetachedTestContainerViewOnMainSync( |
| 409 final AwContentsClient awContentsClient) { |
| 410 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<AwTestC
ontainerView>() { |
| 411 @Override |
| 412 public AwTestContainerView call() { |
| 413 AwTestContainerView detachedView = |
| 414 createDetachedAwTestContainerView(awContentsClient); |
| 415 detachedView.setClipBounds(new Rect(0, 0, 100, 100)); |
| 416 detachedView.measure(100, 100); |
| 417 detachedView.layout(0, 0, 100, 100); |
| 418 return detachedView; |
| 419 } |
| 420 }); |
| 421 } |
| 422 |
| 406 @Feature({"AndroidWebView"}) | 423 @Feature({"AndroidWebView"}) |
| 407 @SmallTest | 424 @SmallTest |
| 408 public void testVisualStateCallbackWhenContainerViewDetached() | 425 public void testVisualStateCallbackWhenContainerViewDetached() throws Throwa
ble { |
| 409 throws Throwable { | |
| 410 final CountDownLatch readyToEnterFullscreenSignal = new CountDownLatch(1
); | |
| 411 final CountDownLatch hasCustomViewSignal = new CountDownLatch(1); | |
| 412 final CountDownLatch testFinishedSignal = new CountDownLatch(1); | 426 final CountDownLatch testFinishedSignal = new CountDownLatch(1); |
| 413 | 427 |
| 414 final AtomicReference<AwContents> awContentsRef = new AtomicReference<>(
); | 428 final TestAwContentsClient awContentsClient = new TestAwContentsClient()
; |
| 415 final AtomicReference<View> customViewRef = new AtomicReference<>(); | 429 final AwTestContainerView testView = |
| 430 createDetachedTestContainerViewOnMainSync(awContentsClient); |
| 431 final AwContents awContents = testView.getAwContents(); |
| 432 final ContentViewCore contentViewCore = testView.getContentViewCore(); |
| 416 | 433 |
| 417 final TestAwContentsClient awContentsClient = new TestAwContentsClient()
{ | 434 enableJavaScriptOnUiThread(awContents); |
| 418 @Override | |
| 419 public void onPageFinished(String url) { | |
| 420 super.onPageFinished(url); | |
| 421 readyToEnterFullscreenSignal.countDown(); | |
| 422 } | |
| 423 | 435 |
| 424 @Override | 436 // JS will notify this observer once it has changed the background color
of the page. |
| 425 public void onShowCustomView( | 437 final Object pageChangeNotifier = new Object() { |
| 426 final View customView, WebChromeClient.CustomViewCallback ca
llback) { | 438 public void onPageChanged() { |
| 427 // Please note that we don't attach the custom view to the windo
w here | 439 ThreadUtils.postOnUiThread(new Runnable() { |
| 428 // (awContentsClient is an instance of TestAwContentsClient, not | 440 @Override |
| 429 // FullScreenVideoTestAwContentsClient). | 441 public void run() { |
| 430 customView.setClipBounds(new Rect(0, 0, 100, 100)); | 442 awContents.insertVisualStateCallback(20, new VisualState
Callback() { |
| 431 customView.measure(100, 100); | 443 @Override |
| 432 customView.layout(0, 0, 100, 100); | 444 public void onComplete(long id) { |
| 433 customViewRef.set(customView); | 445 Bitmap redScreenshot = |
| 434 hasCustomViewSignal.countDown(); | 446 GraphicsTestUtils.drawAwContents(awConte
nts, 100, 100); |
| 447 assertEquals(Color.RED, redScreenshot.getPixel(5
0, 50)); |
| 448 testFinishedSignal.countDown(); |
| 449 } |
| 450 }); |
| 451 } |
| 452 }); |
| 435 } | 453 } |
| 436 }; | 454 }; |
| 437 final AwTestContainerView testView = createAwTestContainerViewOnMainSync
(awContentsClient); | |
| 438 final AwContents awContents = testView.getAwContents(); | |
| 439 awContentsRef.set(awContents); | |
| 440 final ContentViewCore contentViewCore = testView.getContentViewCore(); | |
| 441 enableJavaScriptOnUiThread(awContents); | |
| 442 awContents.getSettings().setFullscreenSupported(true); | |
| 443 | |
| 444 // JS will notify this observer once it has entered fullscreen. | |
| 445 final JavascriptEventObserver jsObserver = new JavascriptEventObserver()
; | |
| 446 runTestOnUiThread(new Runnable() { | |
| 447 @Override | |
| 448 public void run() { | |
| 449 jsObserver.register(contentViewCore, "jsObserver"); | |
| 450 } | |
| 451 }); | |
| 452 | |
| 453 loadUrlSync(awContents, awContentsClient.getOnPageFinishedHelper(), FULL
SCREEN_TEST_URL); | |
| 454 | |
| 455 assertTrue(readyToEnterFullscreenSignal.await( | |
| 456 AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); | |
| 457 DOMUtils.clickNode(VisualStateTest.this, contentViewCore, ENTER_FULLSCRE
EN_CONTROL_ID); | |
| 458 | |
| 459 assertTrue(hasCustomViewSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUni
t.MILLISECONDS)); | |
| 460 assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS)); | |
| 461 | 455 |
| 462 runTestOnUiThread(new Runnable() { | 456 runTestOnUiThread(new Runnable() { |
| 463 @Override | 457 @Override |
| 464 public void run() { | 458 public void run() { |
| 465 awContents.insertVisualStateCallback(20, new VisualStateCallback
() { | 459 contentViewCore.addPossiblyUnsafeJavascriptInterface( |
| 466 @Override | 460 pageChangeNotifier, "pageChangeNotifier", null); |
| 467 public void onComplete(long id) { | 461 awContents.loadUrl(WAIT_FOR_JS_DETACHED_TEST_URL); |
| 468 assertFalse(customViewRef.get().isAttachedToWindow()); | |
| 469 // NOTE: We cannot use drawAwContents here because the w
eb contents | |
| 470 // are rendered into the custom view while in fullscreen
. | |
| 471 Bitmap redScreenshot = GraphicsTestUtils.drawView( | |
| 472 customViewRef.get(), 100, 100); | |
| 473 assertEquals(Color.RED, redScreenshot.getPixel(50, 50)); | |
| 474 testFinishedSignal.countDown(); | |
| 475 } | |
| 476 }); | |
| 477 } | 462 } |
| 478 }); | 463 }); |
| 479 | 464 |
| 480 assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit
.MILLISECONDS)); | 465 assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit
.MILLISECONDS)); |
| 481 } | 466 } |
| 482 | 467 |
| 483 private static final LoadUrlParams createTestPageUrl(String backgroundColor)
{ | 468 private static final LoadUrlParams createTestPageUrl(String backgroundColor)
{ |
| 484 return LoadUrlParams.createLoadDataParams( | 469 return LoadUrlParams.createLoadDataParams( |
| 485 "<html><body bgcolor=" + backgroundColor + "></body></html>", "t
ext/html", false); | 470 "<html><body bgcolor=" + backgroundColor + "></body></html>", "t
ext/html", false); |
| 486 } | 471 } |
| 487 } | 472 } |
| OLD | NEW |