/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; import org.apache.cordova.LOG; import android.os.Looper; import android.test.InstrumentationTestCase; import com.amazon.android.webkit.AmazonWebBackForwardList; import com.amazon.android.webkit.AmazonWebHistoryItem; import com.amazon.android.webkit.AmazonWebView; import junit.framework.Assert; /** * Many tests need to run WebView code in the UI thread. This class wraps a WebView so that calls are ensured to arrive * on the UI thread. All methods may be run on either the UI thread or test thread. */ public class AmazonWebViewOnUiThread { /** * The test that this class is being used in. Used for runTestOnUiThread. */ private InstrumentationTestCase mTest; /** * The WebView that calls will be made on. */ private AmazonWebView mWebView; /** * Initializes the webView with a WebViewClient, WebChromeClient, and PictureListener to prepare for * loadUrlAndWaitForCompletion. A new WebViewOnUiThread should be called during setUp so as to reinitialize between * calls. * * @param test * The test in which this is being run. * @param webView * The webView that the methods should call. * @see loadUrlAndWaitForCompletion */ public AmazonWebViewOnUiThread(InstrumentationTestCase test, CordovaWebView webView) { mTest = test; mWebView = webView; } public void loadUrl(final String url) { runOnUiThread(new Runnable() { @Override public void run() { mWebView.loadUrl(url); } }); } public AmazonWebBackForwardList copyBackForwardList() { return getValue(new ValueGetter<AmazonWebBackForwardList>() { @Override public AmazonWebBackForwardList capture() { return mWebView.copyBackForwardList(); } }); } public void printBackForwardList() { runOnUiThread(new Runnable() { @Override public void run() { AmazonWebBackForwardList currentList = copyBackForwardList(); int currentSize = currentList.getSize(); for (int i = 0; i < currentSize; ++i) { AmazonWebHistoryItem item = currentList.getItemAtIndex(i); String url = item.getUrl(); LOG.d("cordovaamzn", "The URL at index: " + Integer.toString(i) + "is " + url); } } }); } public String getUrl() { return getValue(new ValueGetter<String>() { @Override public String capture() { return mWebView.getUrl(); } }); } public boolean backHistory() { return getValue(new ValueGetter<Boolean>() { @Override public Boolean capture() { // Check webview first to see if there is a history // This is needed to support curPage#diffLink, since they are // added to appView's history, but not our history url array // (JQMobile behavior) if (mWebView.canGoBack()) { printBackForwardList(); mWebView.goBack(); return true; } return false; } }); } /** * Helper for running code on the UI thread where an exception is a test failure. If this is already the UI thread * then it runs the code immediately. * * @see runTestOnUiThread * @param r * The code to run in the UI thread */ public void runOnUiThread(Runnable r) { try { if (isUiThread()) { r.run(); } else { mTest.runTestOnUiThread(r); } } catch (Throwable t) { Assert.fail("Unexpected error while running on UI thread: " + t.getMessage()); } } private <T> T getValue(ValueGetter<T> getter) { runOnUiThread(getter); return getter.getValue(); } private abstract class ValueGetter<T> implements Runnable { private T mValue; @Override public void run() { mValue = capture(); } protected abstract T capture(); public T getValue() { return mValue; } } /* * Returns true if the current thread is the UI thread based on the Looper. */ private static boolean isUiThread() { return (Looper.myLooper() == Looper.getMainLooper()); } }