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 |