• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.browser;
18 
19 import android.app.Instrumentation;
20 import android.net.http.SslError;
21 import android.os.Handler;
22 import android.os.Looper;
23 import android.os.Message;
24 import android.test.ActivityInstrumentationTestCase2;
25 import android.util.Log;
26 import android.webkit.ClientCertRequestHandler;
27 import android.webkit.JsPromptResult;
28 import android.webkit.JsResult;
29 import android.webkit.SslErrorHandler;
30 import android.webkit.WebView;
31 
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.OutputStream;
37 
38 /**
39  * Adds a JavaScript interface to the webview and calls functions on it to verify variables
40  * are passed from JS to Java correctly.
41  * To run this test, execute:
42  * adb shell am instrument -w -e class com.android.browser.JNIBindingsTestApp#testJNIBindings \
43  *     com.android.browser.tests/android.test.InstrumentationTestRunner
44  */
45 public class JNIBindingsTestApp extends ActivityInstrumentationTestCase2<BrowserActivity> {
46 
47     private final static String TAG = "JNIBindingsTest";
48 
49     private static final String SDCARD_BINDINGS_TEST_HTML = "/sdcard/bindings_test.html";
50 
51     private static final int MSG_WEBKIT_DATA_READY = 101;
52 
53     private BrowserActivity mActivity = null;
54     private Controller mController = null;
55     private Instrumentation mInst = null;
56 
57     private boolean mTestDone = false;
58     private String mWebKitResult;
59 
60     private String mExpectedWebKitResult = "Running JNI Bindings test...\n" +
61             "testPrimitiveTypes passed!\n" +
62             "testObjectTypes passed!\n" +
63             "testArray passed!\n" +
64             "testObjectArray passed!\n" +
65             "testObjectMembers passed!\n" +
66             "testJSPrimitivesToStringsInJava passed!\n" +
67             "testJavaReturnTypes passed!\n" +
68             "getIfaceProperties passed!\n" +
69             "testParameterTypeMismatch passed!\n";
70 
71 
72     private class GetWebKitDataThread extends Thread {
73         private JNIBindingsTestApp mTestApp;
74         private WebView mWebView;
75         private Handler mHandler;
76 
GetWebKitDataThread(JNIBindingsTestApp testApp, WebView webView)77         GetWebKitDataThread(JNIBindingsTestApp testApp, WebView webView) {
78             mTestApp = testApp;
79             mWebView = webView;
80         }
81 
82         @Override
run()83         public void run() {
84             Looper.prepare();
85             mHandler = new Handler() {
86                 @Override
87                 public void handleMessage(Message msg) {
88                     switch (msg.what) {
89                         case MSG_WEBKIT_DATA_READY: {
90                             mTestApp.setWebKitResult((String)msg.obj);
91                             Looper.myLooper().quit();
92                         }
93                         default: super.handleMessage(msg); break;
94                     }
95                 }
96             };
97             mWebView.documentAsText(mHandler.obtainMessage(MSG_WEBKIT_DATA_READY, 1, 0));
98             Looper.loop();
99         }
100     }
101 
setWebKitResult(String result)102     public synchronized void setWebKitResult(String result) {
103        mWebKitResult = result;
104        notify();
105     }
106 
JNIBindingsTestApp()107     public JNIBindingsTestApp() {
108         super(BrowserActivity.class);
109     }
110 
111     @Override
setUp()112     protected void setUp() throws Exception {
113         super.setUp();
114 
115         mActivity = getActivity();
116         mController = mActivity.getController();
117         mInst = getInstrumentation();
118         mInst.waitForIdleSync();
119 
120         extractAsset();
121     }
122 
123     @Override
tearDown()124     protected void tearDown() throws Exception {
125         removeAsset();
126         super.tearDown();
127     }
128 
extractAsset()129     protected void extractAsset() throws IOException {
130         InputStream in = getInstrumentation().getContext().getAssets().open("bindings_test.html");
131         OutputStream out = new FileOutputStream(SDCARD_BINDINGS_TEST_HTML);
132 
133         byte[] buf = new byte[2048];
134         int len;
135 
136         while ((len = in.read(buf)) >= 0 ) {
137             out.write(buf, 0, len);
138         }
139         out.close();
140         in.close();
141     }
142 
removeAsset()143     protected void removeAsset(){
144         File fileToDelete = new File(SDCARD_BINDINGS_TEST_HTML);
145         fileToDelete.delete();
146     }
147 
148     /**
149      * Gets the browser ready for testing by starting the application
150      * and wrapping the WebView's helper clients.
151      */
setUpBrowser()152     void setUpBrowser() {
153         Tab tab = mController.getTabControl().getCurrentTab();
154         WebView webView = tab.getWebView();
155         webView.addJavascriptInterface(new JNIBindingsTest(this), "JNIBindingsTest");
156 
157         webView.setWebChromeClient(new TestWebChromeClient(webView.getWebChromeClient()) {
158 
159             /**
160              * Dismisses and logs Javascript alerts.
161              */
162             @Override
163             public boolean onJsAlert(WebView view, String url, String message,
164                     JsResult result) {
165                 String logMsg = String.format("JS Alert '%s' received from %s", message, url);
166                 Log.w(TAG, logMsg);
167                 result.confirm();
168 
169                 return true;
170             }
171 
172             /**
173              * Confirms and logs Javascript alerts.
174              */
175             @Override
176             public boolean onJsConfirm(WebView view, String url, String message,
177                     JsResult result) {
178                 String logMsg = String.format("JS Confirmation '%s' received from %s",
179                         message, url);
180                 Log.w(TAG, logMsg);
181                 result.confirm();
182 
183                 return true;
184             }
185 
186             /**
187              * Confirms and logs Javascript alerts, providing the default value.
188              */
189             @Override
190             public boolean onJsPrompt(WebView view, String url, String message,
191                     String defaultValue, JsPromptResult result) {
192                 String logMsg = String.format("JS Prompt '%s' received from %s; " +
193                         "Giving default value '%s'", message, url, defaultValue);
194                 Log.w(TAG, logMsg);
195                 result.confirm(defaultValue);
196 
197                 return true;
198             }
199         });
200 
201         webView.setWebViewClient(new TestWebViewClient(webView.getWebViewClient()) {
202 
203             /**
204              * Bypasses and logs errors.
205              */
206             @Override
207             public void onReceivedError(WebView view, int errorCode,
208                     String description, String failingUrl) {
209                 String message = String.format("Error '%s' (%d) loading url: %s",
210                         description, errorCode, failingUrl);
211                 Log.w(TAG, message);
212             }
213 
214             /**
215              * Ignores and logs SSL errors.
216              */
217             @Override
218             public void onReceivedSslError(WebView view, SslErrorHandler handler,
219                     SslError error) {
220                 Log.w(TAG, "SSL error: " + error);
221                 handler.proceed();
222             }
223 
224             /**
225              * Ignores and logs SSL client certificate requests.
226              */
227             @Override
228             public void onReceivedClientCertRequest(WebView view, ClientCertRequestHandler handler,
229                     String host_and_port) {
230                 Log.w(TAG, "SSL client certificate request: " + host_and_port);
231                 handler.cancel();
232             }
233 
234         });
235     }
236 
notifyComplete()237     public synchronized void notifyComplete() {
238         mTestDone = true;
239         notify();
240     }
241 
testJNIBindings()242     public void testJNIBindings() {
243         setUpBrowser();
244 
245         Tab tab = mController.getTabControl().getCurrentTab();
246         WebView webView = tab.getWebView();
247         webView.loadUrl("file://" + SDCARD_BINDINGS_TEST_HTML);
248         synchronized(this) {
249             while(!mTestDone) {
250                 try {
251                     wait();
252                 } catch (InterruptedException e) {}
253             }
254         }
255 
256         // Now the tests are complete grab the DOM content and compare to the reference.
257         GetWebKitDataThread getWKData = new GetWebKitDataThread(this, webView);
258         mWebKitResult = null;
259         getWKData.start();
260 
261         synchronized(this) {
262             while(mWebKitResult == null) {
263                 try {
264                     wait();
265                 } catch (InterruptedException e) {}
266             }
267         }
268 
269         Log.v(TAG, "WebKit result:");
270         Log.v(TAG, mWebKitResult);
271         assertEquals("Bindings test failed! See logcat for more details!", mExpectedWebKitResult,
272                 mWebKitResult);
273     }
274 }
275