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 3 // found in the LICENSE file. 4 5 package org.chromium.webview_shell; 6 7 import android.app.Activity; 8 import android.os.Bundle; 9 10 import android.webkit.ConsoleMessage; 11 import android.webkit.GeolocationPermissions; 12 import android.webkit.PermissionRequest; 13 import android.webkit.WebChromeClient; 14 import android.webkit.WebSettings; 15 import android.webkit.WebView; 16 import android.webkit.WebViewClient; 17 18 import java.util.concurrent.TimeUnit; 19 import java.util.concurrent.TimeoutException; 20 21 /** 22 * This activity is used for running layout tests using webview. The activity 23 * creates a webview instance, loads url and captures console messages from 24 * JavaScript until the test is finished. 25 * provides a blocking callback. 26 */ 27 public class WebViewLayoutTestActivity extends Activity { 28 29 private final StringBuilder mConsoleLog = new StringBuilder(); 30 private final Object mLock = new Object(); 31 private static final String TEST_FINISHED_SENTINEL = "TEST FINISHED"; 32 33 private WebView mWebView; 34 private boolean mFinished = false; 35 36 private static final String[] AUTOMATICALLY_GRANT = 37 { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE }; 38 39 @Override onCreate(Bundle savedInstanceState)40 public void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 setContentView(R.layout.activity_webview); 43 mWebView = (WebView) findViewById(R.id.webview); 44 WebSettings settings = mWebView.getSettings(); 45 initializeSettings(settings); 46 47 mWebView.setWebViewClient(new WebViewClient() { 48 @Override 49 public boolean shouldOverrideUrlLoading(WebView webView, String url) { 50 return false; 51 } 52 }); 53 54 mWebView.setWebChromeClient(new WebChromeClient() { 55 @Override 56 public void onGeolocationPermissionsShowPrompt(String origin, 57 GeolocationPermissions.Callback callback) { 58 callback.invoke(origin, true, false); 59 } 60 61 @Override 62 public void onPermissionRequest(PermissionRequest request) { 63 request.grant(AUTOMATICALLY_GRANT); 64 } 65 66 @Override 67 public boolean onConsoleMessage(ConsoleMessage consoleMessage) { 68 // TODO(timvolodine): put log and warnings in separate string builders. 69 mConsoleLog.append(consoleMessage.message() + "\n"); 70 if (consoleMessage.message().equals(TEST_FINISHED_SENTINEL)) { 71 finishTest(); 72 } 73 return true; 74 } 75 }); 76 } 77 waitForFinish(long timeout, TimeUnit unit)78 public void waitForFinish(long timeout, TimeUnit unit) throws InterruptedException, 79 TimeoutException { 80 synchronized (mLock) { 81 long deadline = System.currentTimeMillis() + unit.toMillis(timeout); 82 while (!mFinished && System.currentTimeMillis() < deadline) { 83 mLock.wait(deadline - System.currentTimeMillis()); 84 } 85 if (!mFinished) { 86 throw new TimeoutException("timeout"); 87 } 88 } 89 } 90 getTestResult()91 public String getTestResult() { 92 return mConsoleLog.toString(); 93 } 94 loadUrl(String url)95 public void loadUrl(String url) { 96 mWebView.loadUrl(url); 97 mWebView.requestFocus(); 98 } 99 initializeSettings(WebSettings settings)100 private void initializeSettings(WebSettings settings) { 101 settings.setJavaScriptEnabled(true); 102 settings.setGeolocationEnabled(true); 103 } 104 finishTest()105 private void finishTest() { 106 mFinished = true; 107 synchronized (mLock) { 108 mLock.notifyAll(); 109 } 110 } 111 } 112