125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller// Copyright 2015 The Chromium Authors. All rights reserved. 225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller// Use of this source code is governed by a BSD-style license that can be 325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller// found in the LICENSE file. 425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerpackage org.chromium.webview_shell; 625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.app.Activity; 825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.os.Bundle; 925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 1025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.ConsoleMessage; 1125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.GeolocationPermissions; 1225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.PermissionRequest; 1325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.WebChromeClient; 1425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.WebSettings; 1525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.WebView; 1625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport android.webkit.WebViewClient; 1725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 1825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport java.util.concurrent.TimeUnit; 1925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerimport java.util.concurrent.TimeoutException; 2025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 2125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller/** 2225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller * This activity is used for running layout tests using webview. The activity 2325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller * creates a webview instance, loads url and captures console messages from 2425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller * JavaScript until the test is finished. 2525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller * provides a blocking callback. 2625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller */ 2725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Millerpublic class WebViewLayoutTestActivity extends Activity { 2825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 2925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private final StringBuilder mConsoleLog = new StringBuilder(); 3025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private final Object mLock = new Object(); 3125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private static final String TEST_FINISHED_SENTINEL = "TEST FINISHED"; 3225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 3325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private WebView mWebView; 3425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private boolean mFinished = false; 3525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 3625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private static final String[] AUTOMATICALLY_GRANT = 3725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE }; 3825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 3925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller @Override 4025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public void onCreate(Bundle savedInstanceState) { 4125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller super.onCreate(savedInstanceState); 4225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller setContentView(R.layout.activity_webview); 4325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mWebView = (WebView) findViewById(R.id.webview); 4425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller WebSettings settings = mWebView.getSettings(); 4525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller initializeSettings(settings); 4625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 4725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mWebView.setWebViewClient(new WebViewClient() { 4825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller @Override 4925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public boolean shouldOverrideUrlLoading(WebView webView, String url) { 5025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller return false; 5125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 5225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller }); 5325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 5425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mWebView.setWebChromeClient(new WebChromeClient() { 5525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller @Override 5625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public void onGeolocationPermissionsShowPrompt(String origin, 5725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller GeolocationPermissions.Callback callback) { 5825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller callback.invoke(origin, true, false); 5925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 6025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 6125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller @Override 6225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public void onPermissionRequest(PermissionRequest request) { 6325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller request.grant(AUTOMATICALLY_GRANT); 6425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 6525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 6625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller @Override 6725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public boolean onConsoleMessage(ConsoleMessage consoleMessage) { 6825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller // TODO(timvolodine): put log and warnings in separate string builders. 6925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mConsoleLog.append(consoleMessage.message() + "\n"); 7025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller if (consoleMessage.message().equals(TEST_FINISHED_SENTINEL)) { 7125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller finishTest(); 7225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 7325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller return true; 7425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 7525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller }); 7625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 7725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 7825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public void waitForFinish(long timeout, TimeUnit unit) throws InterruptedException, 7925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller TimeoutException { 8025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller synchronized (mLock) { 8125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller long deadline = System.currentTimeMillis() + unit.toMillis(timeout); 8225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller while (!mFinished && System.currentTimeMillis() < deadline) { 8325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mLock.wait(deadline - System.currentTimeMillis()); 8425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 8525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller if (!mFinished) { 8625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller throw new TimeoutException("timeout"); 8725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 8825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 8925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 9025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 9125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public String getTestResult() { 9225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller return mConsoleLog.toString(); 9325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 9425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 9525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller public void loadUrl(String url) { 9625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mWebView.loadUrl(url); 9725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mWebView.requestFocus(); 9825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 9925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 10025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private void initializeSettings(WebSettings settings) { 10125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller settings.setJavaScriptEnabled(true); 10225df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller settings.setGeolocationEnabled(true); 10325df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 10425df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller 10525df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller private void finishTest() { 10625df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mFinished = true; 10725df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller synchronized (mLock) { 10825df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller mLock.notifyAll(); 10925df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 11025df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller } 11125df6673f1c51e755dd4d08cf64666cdff5e0f18Paul Miller} 112