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.Environment;
     22 import android.os.Handler;
     23 import android.os.Looper;
     24 import android.os.Message;
     25 import android.test.ActivityInstrumentationTestCase2;
     26 import android.util.Log;
     27 import android.webkit.JsPromptResult;
     28 import android.webkit.JsResult;
     29 import android.webkit.SslErrorHandler;
     30 import 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  */
     36 public 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