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