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