http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1571b26a/framework/src/org/apache/cordova/CordovaWebView.java ---------------------------------------------------------------------- diff --cc framework/src/org/apache/cordova/CordovaWebView.java index ac73ecb,8d0b4a9..dc871ac mode 100644,100755..100644 --- a/framework/src/org/apache/cordova/CordovaWebView.java +++ b/framework/src/org/apache/cordova/CordovaWebView.java @@@ -1,76 -1,474 +1,76 @@@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashMap; - - import org.json.JSONException; -import java.util.HashSet; + import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.cordova.Config; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginManager; -import org.apache.cordova.PluginResult; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; + import android.content.Context; import android.content.Intent; - import android.view.KeyEvent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.KeyEvent; import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.webkit.WebBackForwardList; -import android.webkit.WebHistoryItem; -import android.webkit.WebChromeClient; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebSettings.LayoutAlgorithm; -import android.widget.FrameLayout; - -/* - * This class is our web view. - * - * @see <a href="http://developer.android.com/guide/webapps/webview.html">WebView guide</a> - * @see <a href="http://developer.android.com/reference/android/webkit/WebView.html">WebView</a> - */ -public class CordovaWebView extends WebView { - - public static final String TAG = "CordovaWebView"; - public static final String CORDOVA_VERSION = "3.6.0-dev"; - - private HashSet<Integer> boundKeyCodes = new HashSet<Integer>(); - - public PluginManager pluginManager; - private boolean paused; +import android.webkit.WebChromeClient.CustomViewCallback; +import android.widget.LinearLayout.LayoutParams; - private BroadcastReceiver receiver; +public interface CordovaWebView { + public static final String CORDOVA_VERSION = "4.0.0-dev"; - View getView(); ++ void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, List<PluginEntry> pluginEntries); - CordovaWebViewClient makeWebViewClient(); - /** Activities and other important classes **/ - private CordovaInterface cordova; - CordovaWebViewClient viewClient; - @SuppressWarnings("unused") - private CordovaChromeClient chromeClient; ++ View getView(); - CordovaChromeClient makeWebChromeClient(); - private String url; ++ CordovaWebViewClient makeWebViewClient(CordovaInterface cordova); - // Flag to track that a loadUrl timeout occurred - int loadUrlTimeout = 0; - - private long lastMenuEventTime = 0; ++ CordovaChromeClient makeWebChromeClient(CordovaInterface cordova); ++ + void setWebViewClient(CordovaWebViewClient webViewClient); - NativeToJsMessageQueue jsMessageQueue; - ExposedJsApi exposedJsApi; + void setWebChromeClient(CordovaChromeClient webChromeClient); - /** custom view created by the browser (a video player for example) */ - private View mCustomView; - private WebChromeClient.CustomViewCallback mCustomViewCallback; + void setId(int i); - private ActivityResult mResult = null; + void setLayoutParams(LayoutParams layoutParams); - private CordovaResourceApi resourceApi; + void setVisibility(int invisible); - class ActivityResult { - - int request; - int result; - Intent incoming; - - public ActivityResult(int req, int res, Intent intent) { - request = req; - result = res; - incoming = intent; - } + Object getParent(); - - } - - static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = - new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - Gravity.CENTER); - - public CordovaWebView(Context context) { - this(context, null); - } + void loadUrl(String url); - public CordovaWebView(Context context, AttributeSet attrs) { - super(context, attrs); - } + void loadUrl(String url, int splashscreenTime); - @Deprecated - public CordovaWebView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } + void loadUrlNow(String url); - @TargetApi(11) - @Deprecated - public CordovaWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) { - super(context, attrs, defStyle, privateBrowsing); - } - - // Use two-phase init so that the control will work with XML layouts. - public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient chromeClient, List<PluginEntry> pluginEntries) { - if (this.cordova != null) { - throw new IllegalStateException(); - } - this.cordova = cordova; - this.viewClient = webViewClient; - this.chromeClient = chromeClient; - super.setWebChromeClient(chromeClient); - super.setWebViewClient(webViewClient); - - pluginManager = new PluginManager(this, this.cordova, pluginEntries); - jsMessageQueue = new NativeToJsMessageQueue(this, cordova); - exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue); - resourceApi = new CordovaResourceApi(this.getContext(), pluginManager); - - initWebViewSettings(); - exposeJsInterface(); - } - - @SuppressLint("SetJavaScriptEnabled") - @SuppressWarnings("deprecation") - private void initWebViewSettings() { - this.setInitialScale(0); - this.setVerticalScrollBarEnabled(false); - // TODO: The Activity is the one that should call requestFocus(). - if (shouldRequestFocusOnInit()) { - this.requestFocusFromTouch(); - } - // Enable JavaScript - WebSettings settings = this.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setJavaScriptCanOpenWindowsAutomatically(true); - settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL); - - // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2) - try { - Method gingerbread_getMethod = WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class }); - - String manufacturer = android.os.Build.MANUFACTURER; - Log.d(TAG, "CordovaWebView is running on device made by: " + manufacturer); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB && - android.os.Build.MANUFACTURER.contains("HTC")) - { - gingerbread_getMethod.invoke(settings, true); - } - } catch (NoSuchMethodException e) { - Log.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8"); - } catch (IllegalArgumentException e) { - Log.d(TAG, "Doing the NavDump failed with bad arguments"); - } catch (IllegalAccessException e) { - Log.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore"); - } catch (InvocationTargetException e) { - Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore."); - } - - //We don't save any form data in the application - settings.setSaveFormData(false); - settings.setSavePassword(false); - - // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist - // while we do this - if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) - Level16Apis.enableUniversalAccess(settings); - // Enable database - // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16 - String databasePath = getContext().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); - settings.setDatabaseEnabled(true); - settings.setDatabasePath(databasePath); - - - //Determine whether we're in debug or release mode, and turn on Debugging! - ApplicationInfo appInfo = getContext().getApplicationContext().getApplicationInfo(); - if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 && - android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { - enableRemoteDebugging(); - } - - settings.setGeolocationDatabasePath(databasePath); + void loadUrlIntoView(final String url); - // Enable DOM storage - settings.setDomStorageEnabled(true); + void loadUrlIntoView(final String url, boolean recreatePlugins); - // Enable built-in geolocation - settings.setGeolocationEnabled(true); - - // Enable AppCache - // Fix for CB-2282 - settings.setAppCacheMaxSize(5 * 1048576); - settings.setAppCachePath(databasePath); - settings.setAppCacheEnabled(true); - - // Fix for CB-1405 - // Google issue 4641 - settings.getUserAgentString(); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - if (this.receiver == null) { - this.receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - getSettings().getUserAgentString(); - } - }; - getContext().registerReceiver(this.receiver, intentFilter); - } - // end CB-1405 - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - private void enableRemoteDebugging() { - try { - WebView.setWebContentsDebuggingEnabled(true); - } catch (IllegalArgumentException e) { - Log.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! "); - e.printStackTrace(); - } - } - - public CordovaChromeClient makeChromeClient(CordovaInterface cordova) { - return new CordovaChromeClient(cordova, this); - } - - public CordovaWebViewClient makeWebViewClient(CordovaInterface cordova) { - if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return new CordovaWebViewClient(cordova, this); - } - return new IceCreamCordovaWebViewClient(cordova, this); - } - - /** - * Override this method to decide whether or not you need to request the - * focus when your application start - * - * @return true unless this method is overriden to return a different value - */ - protected boolean shouldRequestFocusOnInit() { - return true; - } - - private void exposeJsInterface() { - if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) { - Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old."); - // Bug being that Java Strings do not get converted to JS strings automatically. - // This isn't hard to work-around on the JS side, but it's easier to just - // use the prompt bridge instead. - return; - } - this.addJavascriptInterface(exposedJsApi, "_cordovaNative"); - } + void loadUrlIntoView(final String url, final int splashscreenTime); - /** - * Set the WebViewClient. - */ - @Deprecated // Set this in init() instead. - public void setWebViewClient(CordovaWebViewClient client) { - this.viewClient = client; - super.setWebViewClient(client); - } + void stopLoading(); - /** - * Set the WebChromeClient. - */ - @Deprecated // Set this in init() instead. - public void setWebChromeClient(CordovaChromeClient client) { - this.chromeClient = client; - super.setWebChromeClient(client); - } - - public CordovaChromeClient getWebChromeClient() { - return this.chromeClient; - } + boolean canGoBack(); - /** - * Load the url into the webview. - * - * @param url - */ - @Override - public void loadUrl(String url) { - if (url.equals("about:blank") || url.startsWith("javascript:")) { - this.loadUrlNow(url); - } - else { - this.loadUrlIntoView(url); - } - } + void clearCache(boolean b); - /** - * Load the url into the webview after waiting for period of time. - * This is used to display the splashscreen for certain amount of time. - * - * @param url - * @param time The number of ms to wait before loading webview - */ - @Deprecated - public void loadUrl(final String url, int time) { - if(url == null) - { - this.loadUrlIntoView(Config.getStartUrl()); - } - else - { - this.loadUrlIntoView(url); - } - } - - public void loadUrlIntoView(final String url) { - loadUrlIntoView(url, true); - } + void clearHistory(); - /** - * Load the url into the webview. - * - * @param url - */ - public void loadUrlIntoView(final String url, boolean recreatePlugins) { - LOG.d(TAG, ">>> loadUrl(" + url + ")"); - - if (recreatePlugins) { - this.url = url; - this.pluginManager.init(); - } - - // Create a timeout timer for loadUrl - final CordovaWebView me = this; - final int currentLoadUrlTimeout = me.loadUrlTimeout; - final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("LoadUrlTimeoutValue", "20000")); - - // Timeout error method - final Runnable loadError = new Runnable() { - public void run() { - me.stopLoading(); - LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!"); - if (viewClient != null) { - viewClient.onReceivedError(me, -6, "The connection to the server was unsuccessful.", url); - } - } - }; - - // Timeout timer method - final Runnable timeoutCheck = new Runnable() { - public void run() { - try { - synchronized (this) { - wait(loadUrlTimeoutValue); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - - // If timeout, then stop loading and handle error - if (me.loadUrlTimeout == currentLoadUrlTimeout) { - me.cordova.getActivity().runOnUiThread(loadError); - } - } - }; - - // Load url - this.cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - cordova.getThreadPool().execute(timeoutCheck); - me.loadUrlNow(url); - } - }); - } + boolean backHistory(); - /** - * Load URL in webview. - * - * @param url - */ - void loadUrlNow(String url) { - if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) { - LOG.d(TAG, ">>> loadUrlNow()"); - } - if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) { - super.loadUrl(url); - } - } + void handlePause(boolean keepRunning); - /** - * Load the url into the webview after waiting for period of time. - * This is used to display the splashscreen for certain amount of time. - * - * @param url - * @param time The number of ms to wait before loading webview - */ - public void loadUrlIntoView(final String url, final int time) { + void onNewIntent(Intent intent); - // If not first page of app, then load immediately - // Add support for browser history if we use it. - if ((url.startsWith("javascript:")) || this.canGoBack()) { - } + void handleResume(boolean keepRunning, boolean activityResultKeepRunning); - // If first page, then show splashscreen - else { + void handleDestroy(); - LOG.d(TAG, "loadUrlIntoView(%s, %d)", url, time); + void postMessage(String id, Object data); - // Send message to show splashscreen now if desired - this.postMessage("splashscreen", "show"); - } + void addJavascript(String statement); - // Load url - this.loadUrlIntoView(url); - } - - @Override - public void stopLoading() { - viewClient.isCurrentlyLoading = false; - super.stopLoading(); - } - - public void onScrollChanged(int l, int t, int oldl, int oldt) - { - super.onScrollChanged(l, t, oldl, oldt); - //We should post a message that the scroll changed - ScrollEvent myEvent = new ScrollEvent(l, t, oldl, oldt, this); - this.postMessage("onScrollChanged", myEvent); - } - /** * Send JavaScript statement back to JavaScript. + * (This is a convenience method) + * + * @param statement * Deprecated (https://issues.apache.org/jira/browse/CB-6851) * Instead of executing snippets of JS, you should use the exec bridge * to create a Java->JS communication channel. @@@ -90,46 -488,428 +90,47 @@@ * savedCallbackContext.sendPluginResult(dataResult); */ @Deprecated - public void sendJavascript(String statement) { - this.jsMessageQueue.addJavaScript(statement); - } + void sendJavascript(String statememt); - /** - * Send a plugin result back to JavaScript. - * (This is a convenience method) - * - * @param result - * @param callbackId - */ - public void sendPluginResult(PluginResult result, String callbackId) { - this.jsMessageQueue.addPluginResult(result, callbackId); - } + CordovaChromeClient getWebChromeClient(); - /** - * Send a message to all plugins. - * - * @param id The message id - * @param data The message data - */ - public void postMessage(String id, Object data) { - if (this.pluginManager != null) { - this.pluginManager.postMessage(id, data); - } - } + CordovaPlugin getPlugin(String initCallbackClass); + void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params); - /** - * Go to previous page in history. (We manage our own history) - * - * @return true if we went back, false if we are already at top - */ - public boolean backHistory() { + Object getFocusedChild(); - // 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 (super.canGoBack()) { - printBackForwardList(); - super.goBack(); - - return true; - } - return false; - } + boolean isCustomViewShowing(); + void showCustomView(View view, CustomViewCallback callback); - /** - * Load the specified URL in the Cordova webview or a new browser instance. - * - * NOTE: If openExternal is false, only URLs listed in whitelist can be loaded. - * - * @param url The url to load. - * @param openExternal Load url in browser instead of Cordova webview. - * @param clearHistory Clear the history stack, so new page becomes top of history - * @param params Parameters for new app - */ - public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) { - LOG.d(TAG, "showWebPage(%s, %b, %b, HashMap", url, openExternal, clearHistory); - - // If clearing history - if (clearHistory) { - this.clearHistory(); - } - - // If loading into our webview - if (!openExternal) { - - // Make sure url is in whitelist - if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) { - // TODO: What about params? - // Load new URL - this.loadUrl(url); - return; - } - // Load in default viewer if not - LOG.w(TAG, "showWebPage: Cannot load URL into webview since it is not in white list. Loading into browser instead. (URL=" + url + ")"); - } - try { - // Omitting the MIME type for file: URLs causes "No Activity found to handle Intent". - // Adding the MIME type to http: URLs causes them to not be handled by the downloader. - Intent intent = new Intent(Intent.ACTION_VIEW); - Uri uri = Uri.parse(url); - if ("file".equals(uri.getScheme())) { - intent.setDataAndType(uri, resourceApi.getMimeType(uri)); - } else { - intent.setData(uri); - } - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(TAG, "Error loading url " + url, e); - } - } + void hideCustomView(); - /** - * Get string property for activity. - * - * @param name - * @param defaultValue - * @return the String value for the named property - */ - public String getProperty(String name, String defaultValue) { - Bundle bundle = this.cordova.getActivity().getIntent().getExtras(); - if (bundle == null) { - return defaultValue; - } - name = name.toLowerCase(Locale.getDefault()); - Object p = bundle.get(name); - if (p == null) { - return defaultValue; - } - return p.toString(); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - if(boundKeyCodes.contains(keyCode)) - { - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { - this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');"); - return true; - } - // If volumeup key - else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');"); - return true; - } - else - { - return super.onKeyDown(keyCode, event); - } - } - else if(keyCode == KeyEvent.KEYCODE_BACK) - { - return !(this.startOfHistory()) || isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK); - } - else if(keyCode == KeyEvent.KEYCODE_MENU) - { - //How did we get here? Is there a childView? - View childView = this.getFocusedChild(); - if(childView != null) - { - //Make sure we close the keyboard if it's present - InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(childView.getWindowToken(), 0); - cordova.getActivity().openOptionsMenu(); - return true; - } else { - return super.onKeyDown(keyCode, event); - } - } - return super.onKeyDown(keyCode, event); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) - { - // If back key - if (keyCode == KeyEvent.KEYCODE_BACK) { - // A custom view is currently displayed (e.g. playing a video) - if(mCustomView != null) { - this.hideCustomView(); - return true; - } else { - // The webview is currently displayed - // If back key is bound, then send event to JavaScript - if (isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK)) { - this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');"); - return true; - } else { - // If not bound - // Go to previous page in webview if it is possible to go back - if (this.backHistory()) { - return true; - } - // If not, then invoke default behavior - } - } - } - // Legacy - else if (keyCode == KeyEvent.KEYCODE_MENU) { - if (this.lastMenuEventTime < event.getEventTime()) { - this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');"); - } - this.lastMenuEventTime = event.getEventTime(); - return super.onKeyUp(keyCode, event); - } - // If search key - else if (keyCode == KeyEvent.KEYCODE_SEARCH) { - this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');"); - return true; - } - - //Does webkit change this behavior? - return super.onKeyUp(keyCode, event); - } - - public void setButtonPlumbedToJs(int keyCode, boolean value) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_BACK: - // TODO: Why are search and menu buttons handled separately? - boundKeyCodes.add(keyCode); - return; - default: - throw new IllegalArgumentException("Unsupported keycode: " + keyCode); - } - } - - @Deprecated // Use setButtonPlumbedToJs() instead. - public void bindButton(boolean override) - { - setButtonPlumbedToJs(KeyEvent.KEYCODE_BACK, override); - } - - @Deprecated // Use setButtonPlumbedToJs() instead. - public void bindButton(String button, boolean override) { - if (button.compareTo("volumeup")==0) { - setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_UP, override); - } - else if (button.compareTo("volumedown")==0) { - setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override); - } - } - - @Deprecated // Use setButtonPlumbedToJs() instead. - public void bindButton(int keyCode, boolean keyDown, boolean override) { - setButtonPlumbedToJs(keyCode, override); - } - - @Deprecated // Use isButtonPlumbedToJs - public boolean isBackButtonBound() - { - return isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK); - } - - public boolean isButtonPlumbedToJs(int keyCode) - { - return boundKeyCodes.contains(keyCode); - } - - public void handlePause(boolean keepRunning) - { - LOG.d(TAG, "Handle the pause"); - // Send pause event to JavaScript - this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};"); - - // Forward to plugins - if (this.pluginManager != null) { - this.pluginManager.onPause(keepRunning); - } - - // If app doesn't want to run in background - if (!keepRunning) { - // Pause JavaScript timers (including setInterval) - this.pauseTimers(); - } - paused = true; - - } - - public void handleResume(boolean keepRunning, boolean activityResultKeepRunning) - { + Context getContext(); - this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};"); - - // Forward to plugins - if (this.pluginManager != null) { - this.pluginManager.onResume(keepRunning); - } - - // Resume JavaScript timers (including setInterval) - this.resumeTimers(); - paused = false; - } - - public void handleDestroy() - { - // Send destroy event to JavaScript - this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};"); - - // Load blank page so that JavaScript onunload is called - this.loadUrl("about:blank"); - - // Forward to plugins - if (this.pluginManager != null) { - this.pluginManager.onDestroy(); - } - - // unregister the receiver - if (this.receiver != null) { - try { - getContext().unregisterReceiver(this.receiver); - } catch (Exception e) { - Log.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e); - } - } - } - - public void onNewIntent(Intent intent) - { - //Forward to plugins - if (this.pluginManager != null) { - this.pluginManager.onNewIntent(intent); - } - } - - public boolean isPaused() - { - return paused; - } - - @Deprecated // This never did anything. - public boolean hadKeyEvent() { - return false; - } - - // Wrapping these functions in their own class prevents warnings in adb like: - // VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs - @TargetApi(16) - private static class Level16Apis { - static void enableUniversalAccess(WebSettings settings) { - settings.setAllowUniversalAccessFromFileURLs(true); - } - } - - public void printBackForwardList() { - WebBackForwardList currentList = this.copyBackForwardList(); - int currentSize = currentList.getSize(); - for(int i = 0; i < currentSize; ++i) - { - WebHistoryItem item = currentList.getItemAtIndex(i); - String url = item.getUrl(); - LOG.d(TAG, "The URL at index: " + Integer.toString(i) + " is " + url ); - } - } - - - //Can Go Back is BROKEN! - public boolean startOfHistory() - { - WebBackForwardList currentList = this.copyBackForwardList(); - WebHistoryItem item = currentList.getItemAtIndex(0); - if( item!=null){ // Null-fence in case they haven't called loadUrl yet (CB-2458) - String url = item.getUrl(); - String currentUrl = this.getUrl(); - LOG.d(TAG, "The current URL is: " + currentUrl); - LOG.d(TAG, "The URL at item 0 is: " + url); - return currentUrl.equals(url); - } - return false; - } - - public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) { - // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0 - Log.d(TAG, "showing Custom View"); - // if a view already exists then immediately terminate the new one - if (mCustomView != null) { - callback.onCustomViewHidden(); - return; - } - - // Store the view and its callback for later (to kill it properly) - mCustomView = view; - mCustomViewCallback = callback; - - // Add the custom view to its container. - ViewGroup parent = (ViewGroup) this.getParent(); - parent.addView(view, COVER_SCREEN_GRAVITY_CENTER); - - // Hide the content view. - this.setVisibility(View.GONE); - - // Finally show the custom view container. - parent.setVisibility(View.VISIBLE); - parent.bringToFront(); - } - - public void hideCustomView() { - // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0 - Log.d(TAG, "Hiding Custom View"); - if (mCustomView == null) return; - - // Hide the custom view. - mCustomView.setVisibility(View.GONE); - - // Remove the custom view from its container. - ViewGroup parent = (ViewGroup) this.getParent(); - parent.removeView(mCustomView); - mCustomView = null; - mCustomViewCallback.onCustomViewHidden(); - - // Show the content view. - this.setVisibility(View.VISIBLE); - } - - /** - * if the video overlay is showing then we need to know - * as it effects back button handling - * - * @return true if custom view is showing - */ - public boolean isCustomViewShowing() { - return mCustomView != null; - } - - public WebBackForwardList restoreState(Bundle savedInstanceState) - { - WebBackForwardList myList = super.restoreState(savedInstanceState); - Log.d(TAG, "WebView restoration crew now restoring!"); - //Initialize the plugin manager once more - this.pluginManager.init(); - return myList; - } - - public void storeResult(int requestCode, int resultCode, Intent intent) { - mResult = new ActivityResult(requestCode, resultCode, intent); - } + boolean onOverrideUrlLoading(String url); + + int getVisibility(); + + void incUrlTimeout(); + + void setOverScrollMode(int overScrollNever); + + void setNetworkAvailable(boolean online); + + CordovaResourceApi getResourceApi(); + + void setButtonPlumbedToJs(int keyCode, boolean override); + boolean isButtonPlumbedToJs(int keyCode); + + void sendPluginResult(PluginResult cr, String callbackId); + + PluginManager getPluginManager(); + + void setLayoutParams(android.widget.FrameLayout.LayoutParams layoutParams); - public CordovaResourceApi getResourceApi() { - return resourceApi; - } + // Required for test + String getUrl(); + boolean isPaused(); ++ }
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1571b26a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java ---------------------------------------------------------------------- diff --cc framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java index 3c6ad21,67793d7..1a29510 --- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java +++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java @@@ -32,16 -32,16 +32,11 @@@ import android.webkit.WebResourceRespon import android.webkit.WebView; @TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class IceCreamCordovaWebViewClient extends CordovaWebViewClient { +public class IceCreamCordovaWebViewClient extends AndroidWebViewClient implements CordovaWebViewClient{ private static final String TAG = "IceCreamCordovaWebViewClient"; -- private CordovaUriHelper helper; -- public IceCreamCordovaWebViewClient(CordovaInterface cordova) { -- super(cordova); -- } -- - public IceCreamCordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) { + public IceCreamCordovaWebViewClient(CordovaInterface cordova, AndroidWebView view) { super(cordova, view); } http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1571b26a/framework/src/org/apache/cordova/PluginManager.java ---------------------------------------------------------------------- diff --cc framework/src/org/apache/cordova/PluginManager.java index 13c55c8,4bd4754..7ba9450 --- a/framework/src/org/apache/cordova/PluginManager.java +++ b/framework/src/org/apache/cordova/PluginManager.java @@@ -19,9 -19,7 +19,8 @@@ package org.apache.cordova; import java.util.HashMap; - import java.util.Iterator; import java.util.List; +import java.util.Set; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CallbackContext; @@@ -54,18 -52,32 +53,33 @@@ public class PluginManager // Stores mapping of Plugin Name -> <url-filter> values. // Using <url-filter> is deprecated. - protected HashMap<String, List<String>> urlMap; + protected HashMap<String, List<String>> urlMap = new HashMap<String, List<String>>(); - @Deprecated - PluginManager(CordovaWebView cordovaWebView, CordovaInterface cordova) { - this(cordovaWebView, cordova, null); - } + private Set<String> pluginIdWhitelist; - public PluginManager(CordovaWebView app, CordovaInterface ctx) { - this.ctx = ctx; - this.app = app; + PluginManager(CordovaWebView cordovaWebView, CordovaInterface cordova, List<PluginEntry> pluginEntries) { + this.ctx = cordova; + this.app = cordovaWebView; + if (pluginEntries == null) { + ConfigXmlParser parser = new ConfigXmlParser(); + parser.parse(ctx.getActivity()); + pluginEntries = parser.getPluginEntries(); + } + setPluginEntries(pluginEntries); + } + + public void setPluginEntries(List<PluginEntry> pluginEntries) { + this.onPause(false); + this.onDestroy(); + this.clearPluginObjects(); + for (PluginEntry entry : pluginEntries) { + addService(entry); + } } + + public void setPluginIdWhitelist(Set<String> pluginIdWhitelist) { + this.pluginIdWhitelist = pluginIdWhitelist; + } /** * Init when loading a new HTML page into webview.
