1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.browser; 18 19import android.app.Instrumentation; 20import android.net.http.SslError; 21import android.os.Environment; 22import android.os.Handler; 23import android.os.Looper; 24import android.os.Message; 25import android.test.ActivityInstrumentationTestCase2; 26import android.util.Log; 27import android.webkit.JsPromptResult; 28import android.webkit.JsResult; 29import android.webkit.SslErrorHandler; 30import android.webkit.WebView; 31 32/** 33 * Adds a JavaScript interface to the webview and calls functions on it to verify variables 34 * are passed from JS to Java correctly. 35 */ 36public class JNIBindingsTestApp extends ActivityInstrumentationTestCase2<BrowserActivity> { 37 38 private final static String TAG = "JNIBindingsTest"; 39 40 private static final int MSG_WEBKIT_DATA_READY = 101; 41 42 private BrowserActivity mActivity = null; 43 private Instrumentation mInst = null; 44 45 private boolean mTestDone = false; 46 private String mWebKitResult; 47 48 private String mExpectedWebKitResult = "Running JNI Bindings test...\n" + 49 "testPrimitiveTypes passed!\n" + 50 "testObjectTypes passed!\n" + 51 "testArray passed!\n" + 52 "testObjectArray passed!\n" + 53 "testObjectMembers passed!\n" + 54 "testJSPrimitivesToStringsInJava passed!\n" + 55 "testJavaReturnTypes passed!\n" + 56 "getIfaceProperties passed!\n" + 57 "testParameterTypeMismatch passed!\n"; 58 59 60 private class GetWebKitDataThread extends Thread { 61 private JNIBindingsTestApp mTestApp; 62 private WebView mWebView; 63 private Handler mHandler; 64 65 GetWebKitDataThread(JNIBindingsTestApp testApp, WebView webView) { 66 mTestApp = testApp; 67 mWebView = webView; 68 } 69 70 public void run() { 71 Looper.prepare(); 72 mHandler = new Handler() { 73 public void handleMessage(Message msg) { 74 switch (msg.what) { 75 case MSG_WEBKIT_DATA_READY: { 76 mTestApp.setWebKitResult((String)msg.obj); 77 Looper.myLooper().quit(); 78 } 79 default: super.handleMessage(msg); break; 80 } 81 } 82 }; 83 mWebView.documentAsText(mHandler.obtainMessage(MSG_WEBKIT_DATA_READY)); 84 Looper.loop(); 85 } 86 } 87 88 public synchronized void setWebKitResult(String result) { 89 mWebKitResult = result; 90 notify(); 91 } 92 93 public JNIBindingsTestApp() { 94 super(BrowserActivity.class); 95 } 96 97 @Override 98 protected void setUp() throws Exception { 99 super.setUp(); 100 101 mActivity = getActivity(); 102 mInst = getInstrumentation(); 103 mInst.waitForIdleSync(); 104 105 } 106 107 /** 108 * Gets the browser ready for testing by starting the application 109 * and wrapping the WebView's helper clients. 110 */ 111 void setUpBrowser() { 112 Tab tab = mActivity.getTabControl().getCurrentTab(); 113 WebView webView = tab.getWebView(); 114 webView.addJavascriptInterface(new JNIBindingsTest(this), "JNIBindingsTest"); 115 116 webView.setWebChromeClient(new TestWebChromeClient(webView.getWebChromeClient()) { 117 118 /** 119 * Dismisses and logs Javascript alerts. 120 */ 121 @Override 122 public boolean onJsAlert(WebView view, String url, String message, 123 JsResult result) { 124 String logMsg = String.format("JS Alert '%s' received from %s", message, url); 125 Log.w(TAG, logMsg); 126 result.confirm(); 127 128 return true; 129 } 130 131 /** 132 * Confirms and logs Javascript alerts. 133 */ 134 @Override 135 public boolean onJsConfirm(WebView view, String url, String message, 136 JsResult result) { 137 String logMsg = String.format("JS Confirmation '%s' received from %s", 138 message, url); 139 Log.w(TAG, logMsg); 140 result.confirm(); 141 142 return true; 143 } 144 145 /** 146 * Confirms and logs Javascript alerts, providing the default value. 147 */ 148 @Override 149 public boolean onJsPrompt(WebView view, String url, String message, 150 String defaultValue, JsPromptResult result) { 151 String logMsg = String.format("JS Prompt '%s' received from %s; " + 152 "Giving default value '%s'", message, url, defaultValue); 153 Log.w(TAG, logMsg); 154 result.confirm(defaultValue); 155 156 return true; 157 } 158 }); 159 160 webView.setWebViewClient(new TestWebViewClient(webView.getWebViewClient()) { 161 162 /** 163 * Bypasses and logs errors. 164 */ 165 @Override 166 public void onReceivedError(WebView view, int errorCode, 167 String description, String failingUrl) { 168 String message = String.format("Error '%s' (%d) loading url: %s", 169 description, errorCode, failingUrl); 170 Log.w(TAG, message); 171 } 172 173 /** 174 * Ignores and logs SSL errors. 175 */ 176 @Override 177 public void onReceivedSslError(WebView view, SslErrorHandler handler, 178 SslError error) { 179 Log.w(TAG, "SSL error: " + error); 180 handler.proceed(); 181 } 182 183 }); 184 } 185 186 public synchronized void testComplete() { 187 mTestDone = true; 188 notify(); 189 } 190 191 public void testJNIBindings() { 192 setUpBrowser(); 193 194 Tab tab = mActivity.getTabControl().getCurrentTab(); 195 WebView webView = tab.getWebView(); 196 webView.loadUrl("file:///sdcard/bindings_test.html"); 197 synchronized(this) { 198 while(!mTestDone) { 199 try { 200 wait(); 201 } catch (InterruptedException e) {} 202 } 203 } 204 205 // Now the tests are complete grab the DOM content and compare to the reference. 206 GetWebKitDataThread getWKData = new GetWebKitDataThread(this, webView); 207 mWebKitResult = null; 208 getWKData.start(); 209 210 synchronized(this) { 211 while(mWebKitResult == null) { 212 try { 213 wait(); 214 } catch (InterruptedException e) {} 215 } 216 } 217 218 Log.v(TAG, "WebKit result:"); 219 Log.v(TAG, mWebKitResult); 220 assertEquals("Bindings test failed! See logcat for more details!", mExpectedWebKitResult, 221 mWebKitResult); 222 } 223} 224