From a88b8de8207130231836ff4c2b67159c8c48b0ba Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Tue, 22 Oct 2013 15:43:21 -0400 Subject: [PATCH] Update InAppBrowser.java to cordova-plugin-inappbrowser@aa81c3267a5b1c337b09933ff5ceb06a93f9dbb7 --- .../src/org/apache/cordova/InAppBrowser.java | 454 ++++++++---------- .../org/apache/cordova/InAppChromeClient.java | 128 +++++ 2 files changed, 320 insertions(+), 262 deletions(-) create mode 100644 framework/src/org/apache/cordova/InAppChromeClient.java diff --git a/framework/src/org/apache/cordova/InAppBrowser.java b/framework/src/org/apache/cordova/InAppBrowser.java index 88558dc6..148328da 100644 --- a/framework/src/org/apache/cordova/InAppBrowser.java +++ b/framework/src/org/apache/cordova/InAppBrowser.java @@ -18,24 +18,12 @@ */ package org.apache.cordova; -import java.util.HashMap; -import java.util.StringTokenizer; - -import org.apache.cordova.api.CallbackContext; -import org.apache.cordova.api.CordovaPlugin; -import org.apache.cordova.api.LOG; -import org.apache.cordova.api.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; -import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.text.InputType; @@ -49,11 +37,8 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; -import android.webkit.WebChromeClient; -import android.webkit.GeolocationPermissions.Callback; -import android.webkit.JsPromptResult; +import android.webkit.CookieManager; import android.webkit.WebSettings; -import android.webkit.WebStorage; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; @@ -61,6 +46,19 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout; +import org.apache.cordova.Config; +import org.apache.cordova.CordovaArgs; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.api.CallbackContext; +import org.apache.cordova.api.CordovaPlugin; +import org.apache.cordova.api.LOG; +import org.apache.cordova.api.PluginResult; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.StringTokenizer; + @SuppressLint("SetJavaScriptEnabled") public class InAppBrowser extends CordovaPlugin { @@ -76,7 +74,8 @@ public class InAppBrowser extends CordovaPlugin { private static final String LOAD_STOP_EVENT = "loadstop"; private static final String LOAD_ERROR_EVENT = "loaderror"; private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption"; - private long MAX_QUOTA = 100 * 1024 * 1024; + private static final String CLEAR_ALL_CACHE = "clearcache"; + private static final String CLEAR_SESSION_CACHE = "clearsessioncache"; private Dialog dialog; private WebView inAppWebView; @@ -85,7 +84,9 @@ public class InAppBrowser extends CordovaPlugin { private boolean showLocationBar = true; private boolean openWindowHidden = false; private String buttonLabel = "Done"; - + private boolean clearAllCache= false; + private boolean clearSessionCache=false; + /** * Executes the request and returns PluginResult. * @@ -94,118 +95,134 @@ public class InAppBrowser extends CordovaPlugin { * @param callbackId The callback id used when calling back into JavaScript. * @return A PluginResult object with a status and message. */ - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - try { - if (action.equals("open")) { - this.callbackContext = callbackContext; - String url = args.getString(0); - String target = args.optString(1); - if (target == null || target.equals("") || target.equals(NULL)) { - target = SELF; - } - HashMap features = parseFeature(args.optString(2)); - - Log.d(LOG_TAG, "target = " + target); - - url = updateUrl(url); - String result = ""; - - // SELF - if (SELF.equals(target)) { - Log.d(LOG_TAG, "in self"); - // load in webview - if (url.startsWith("file://") || url.startsWith("javascript:") - || Config.isUrlWhiteListed(url)) { - this.webView.loadUrl(url); - } - //Load the dialer - else if (url.startsWith(WebView.SCHEME_TEL)) - { - try { - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.setData(Uri.parse(url)); - this.cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); + public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException { + if (action.equals("open")) { + this.callbackContext = callbackContext; + final String url = args.getString(0); + String t = args.optString(1); + if (t == null || t.equals("") || t.equals(NULL)) { + t = SELF; + } + final String target = t; + final HashMap features = parseFeature(args.optString(2)); + + Log.d(LOG_TAG, "target = " + target); + + this.cordova.getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + String result = ""; + // SELF + if (SELF.equals(target)) { + Log.d(LOG_TAG, "in self"); + // load in webview + if (url.startsWith("file://") || url.startsWith("javascript:") + || Config.isUrlWhiteListed(url)) { + webView.loadUrl(url); + } + //Load the dialer + else if (url.startsWith(WebView.SCHEME_TEL)) + { + try { + Intent intent = new Intent(Intent.ACTION_DIAL); + intent.setData(Uri.parse(url)); + cordova.getActivity().startActivity(intent); + } catch (android.content.ActivityNotFoundException e) { + LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); + } + } + // load in InAppBrowser + else { + result = showWebPage(url, features); } } - // load in InAppBrowser + // SYSTEM + else if (SYSTEM.equals(target)) { + Log.d(LOG_TAG, "in system"); + result = openExternal(url); + } + // BLANK - or anything else else { - result = this.showWebPage(url, features); + Log.d(LOG_TAG, "in blank"); + result = showWebPage(url, features); } + + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); + pluginResult.setKeepCallback(true); + callbackContext.sendPluginResult(pluginResult); } - // SYSTEM - else if (SYSTEM.equals(target)) { - Log.d(LOG_TAG, "in system"); - result = this.openExternal(url); + }); + } + else if (action.equals("close")) { + closeDialog(); + } + else if (action.equals("injectScriptCode")) { + String jsWrapper = null; + if (args.getBoolean(1)) { + jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId()); + } + injectDeferredObject(args.getString(0), jsWrapper); + } + else if (action.equals("injectScriptFile")) { + String jsWrapper; + if (args.getBoolean(1)) { + jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId()); + } else { + jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)"; + } + injectDeferredObject(args.getString(0), jsWrapper); + } + else if (action.equals("injectStyleCode")) { + String jsWrapper; + if (args.getBoolean(1)) { + jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); + } else { + jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)"; + } + injectDeferredObject(args.getString(0), jsWrapper); + } + else if (action.equals("injectStyleFile")) { + String jsWrapper; + if (args.getBoolean(1)) { + jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); + } else { + jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)"; + } + injectDeferredObject(args.getString(0), jsWrapper); + } + else if (action.equals("show")) { + this.cordova.getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.show(); } - // BLANK - or anything else - else { - Log.d(LOG_TAG, "in blank"); - result = this.showWebPage(url, features); - } - - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); - pluginResult.setKeepCallback(true); - this.callbackContext.sendPluginResult(pluginResult); - } - else if (action.equals("close")) { - closeDialog(); - this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); - } - else if (action.equals("injectScriptCode")) { - String jsWrapper = null; - if (args.getBoolean(1)) { - jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId()); - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectScriptFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleCode")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("show")) { - Runnable runnable = new Runnable() { - @Override - public void run() { - dialog.show(); - } - }; - this.cordova.getActivity().runOnUiThread(runnable); - this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); - } - else { - return false; - } - } catch (JSONException e) { - this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); + }); + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK); + pluginResult.setKeepCallback(true); + this.callbackContext.sendPluginResult(pluginResult); + } + else { + return false; } return true; } + /** + * Called when the view navigates. + */ + @Override + public void onReset() { + closeDialog(); + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + closeDialog(); + } + /** * Inject an object (script or style) into the InAppBrowser WebView. * @@ -233,8 +250,14 @@ public class InAppBrowser extends CordovaPlugin { } else { scriptToInject = source; } + final String finalScriptToInject = scriptToInject; // This action will have the side-effect of blurring the currently focused element - this.inAppWebView.loadUrl("javascript:" + scriptToInject); + this.cordova.getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + inAppWebView.loadUrl("javascript:" + finalScriptToInject); + } + }); } /** @@ -266,20 +289,6 @@ public class InAppBrowser extends CordovaPlugin { } } - /** - * Convert relative URL to full path - * - * @param url - * @return - */ - private String updateUrl(String url) { - Uri newUrl = Uri.parse(url); - if (newUrl.isRelative()) { - url = this.webView.getUrl().substring(0, this.webView.getUrl().lastIndexOf("/")+1) + url; - } - return url; - } - /** * Display a new browser with the specified URL. * @@ -303,20 +312,30 @@ public class InAppBrowser extends CordovaPlugin { /** * Closes the dialog */ - private void closeDialog() { + public void closeDialog() { + final WebView childView = this.inAppWebView; + // The JS protects against multiple calls, so this should happen only when + // closeDialog() is called by other native code. + if (childView == null) { + return; + } + this.cordova.getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + childView.loadUrl("about:blank"); + if (dialog != null) { + dialog.dismiss(); + } + } + }); try { - this.inAppWebView.loadUrl("about:blank"); JSONObject obj = new JSONObject(); obj.put("type", EXIT_EVENT); - sendUpdate(obj, false); } catch (JSONException ex) { Log.d(LOG_TAG, "Should never happen"); } - if (dialog != null) { - dialog.dismiss(); - } } /** @@ -380,9 +399,18 @@ public class InAppBrowser extends CordovaPlugin { showLocationBar = show.booleanValue(); } Boolean hidden = features.get(HIDDEN); - if(hidden != null) { + if (hidden != null) { openWindowHidden = hidden.booleanValue(); } + Boolean cache = features.get(CLEAR_ALL_CACHE); + if (cache != null) { + clearAllCache = cache.booleanValue(); + } else { + cache = features.get(CLEAR_SESSION_CACHE); + if (cache != null) { + clearSessionCache = cache.booleanValue(); + } + } } final CordovaWebView thatWebView = this.webView; @@ -411,14 +439,7 @@ public class InAppBrowser extends CordovaPlugin { dialog.setCancelable(true); dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { public void onDismiss(DialogInterface dialog) { - try { - JSONObject obj = new JSONObject(); - obj.put("type", EXIT_EVENT); - - sendUpdate(obj, false); - } catch (JSONException e) { - Log.d(LOG_TAG, "Should never happen"); - } + closeDialog(); } }); @@ -428,6 +449,8 @@ public class InAppBrowser extends CordovaPlugin { // Toolbar layout RelativeLayout toolbar = new RelativeLayout(cordova.getActivity()); + //Please, no more black! + toolbar.setBackgroundColor(android.graphics.Color.LTGRAY); toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); toolbar.setHorizontalGravity(Gravity.LEFT); @@ -515,22 +538,24 @@ public class InAppBrowser extends CordovaPlugin { settings.setJavaScriptEnabled(true); settings.setJavaScriptCanOpenWindowsAutomatically(true); settings.setBuiltInZoomControls(true); - /** - * We need to be careful of this line as a future Android release may deprecate it out of existence. - * Can't replace it with the API 8 level call right now as our minimum SDK is 7 until May 2013 - */ settings.setPluginState(android.webkit.WebSettings.PluginState.ON); + //Toggle whether this is enabled or not! Bundle appSettings = cordova.getActivity().getIntent().getExtras(); boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); - if(enableDatabase) - { + if (enableDatabase) { String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); settings.setDatabasePath(databasePath); settings.setDatabaseEnabled(true); } settings.setDomStorageEnabled(true); - + + if (clearAllCache) { + CookieManager.getInstance().removeAllCookie(); + } else if (clearSessionCache) { + CookieManager.getInstance().removeSessionCookie(); + } + inAppWebView.loadUrl(url); inAppWebView.setId(6); inAppWebView.getSettings().setLoadWithOverviewMode(true); @@ -589,114 +614,19 @@ public class InAppBrowser extends CordovaPlugin { * * @param obj a JSONObject contain event payload information * @param status the status code to return to the JavaScript environment - */ private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) { - PluginResult result = new PluginResult(status, obj); - result.setKeepCallback(keepCallback); - this.callbackContext.sendPluginResult(result); + */ + private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) { + if (callbackContext != null) { + PluginResult result = new PluginResult(status, obj); + result.setKeepCallback(keepCallback); + callbackContext.sendPluginResult(result); + if (!keepCallback) { + callbackContext = null; + } + } } - public class InAppChromeClient extends WebChromeClient { - private CordovaWebView webView; - - public InAppChromeClient(CordovaWebView webView) { - super(); - this.webView = webView; - } - /** - * Handle database quota exceeded notification. - * - * @param url - * @param databaseIdentifier - * @param currentQuota - * @param estimatedSize - * @param totalUsedQuota - * @param quotaUpdater - */ - @Override - public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, - long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) - { - LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota); - - if (estimatedSize < MAX_QUOTA) - { - //increase for 1Mb - long newQuota = estimatedSize; - LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota); - quotaUpdater.updateQuota(newQuota); - } - else - { - // Set the quota to whatever it is and force an error - // TODO: get docs on how to handle this properly - quotaUpdater.updateQuota(currentQuota); - } - } - - /** - * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin. - * - * @param origin - * @param callback - */ - @Override - public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { - super.onGeolocationPermissionsShowPrompt(origin, callback); - callback.invoke(origin, true, false); - } - - /** - * Tell the client to display a prompt dialog to the user. - * If the client returns true, WebView will assume that the client will - * handle the prompt dialog and call the appropriate JsPromptResult method. - * - * The prompt bridge provided for the InAppBrowser is capable of executing any - * oustanding callback belonging to the InAppBrowser plugin. Care has been - * taken that other callbacks cannot be triggered, and that no other code - * execution is possible. - * - * To trigger the bridge, the prompt default value should be of the form: - * - * gap-iab:// - * - * where is the string id of the callback to trigger (something - * like "InAppBrowser0123456789") - * - * If present, the prompt message is expected to be a JSON-encoded value to - * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid. - * - * @param view - * @param url - * @param message - * @param defaultValue - * @param result - */ - @Override - public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { - // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute. - if (defaultValue != null && defaultValue.startsWith("gap-iab://")) { - PluginResult scriptResult; - String scriptCallbackId = defaultValue.substring(10); - if (scriptCallbackId.startsWith("InAppBrowser")) { - if(message == null || message.length() == 0) { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray()); - } else { - try { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message)); - } catch(JSONException e) { - scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()); - } - } - this.webView.sendPluginResult(scriptResult, scriptCallbackId); - result.confirm(""); - return true; - } - } - return false; - } - - } /** * The webview client receives notifications about appView diff --git a/framework/src/org/apache/cordova/InAppChromeClient.java b/framework/src/org/apache/cordova/InAppChromeClient.java new file mode 100644 index 00000000..fdf944ed --- /dev/null +++ b/framework/src/org/apache/cordova/InAppChromeClient.java @@ -0,0 +1,128 @@ +package org.apache.cordova; + +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.api.LOG; +import org.apache.cordova.api.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; + +import android.webkit.JsPromptResult; +import android.webkit.WebChromeClient; +import android.webkit.WebStorage; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.webkit.GeolocationPermissions.Callback; + +public class InAppChromeClient extends WebChromeClient { + + private CordovaWebView webView; + private String LOG_TAG = "InAppChromeClient"; + private long MAX_QUOTA = 100 * 1024 * 1024; + + public InAppChromeClient(CordovaWebView webView) { + super(); + this.webView = webView; + } + /** + * Handle database quota exceeded notification. + * + * @param url + * @param databaseIdentifier + * @param currentQuota + * @param estimatedSize + * @param totalUsedQuota + * @param quotaUpdater + */ + @Override + public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, + long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) + { + LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota); + + if (estimatedSize < MAX_QUOTA) + { + //increase for 1Mb + long newQuota = estimatedSize; + LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota); + quotaUpdater.updateQuota(newQuota); + } + else + { + // Set the quota to whatever it is and force an error + // TODO: get docs on how to handle this properly + quotaUpdater.updateQuota(currentQuota); + } + } + + /** + * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin. + * + * @param origin + * @param callback + */ + @Override + public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { + super.onGeolocationPermissionsShowPrompt(origin, callback); + callback.invoke(origin, true, false); + } + + /** + * Tell the client to display a prompt dialog to the user. + * If the client returns true, WebView will assume that the client will + * handle the prompt dialog and call the appropriate JsPromptResult method. + * + * The prompt bridge provided for the InAppBrowser is capable of executing any + * oustanding callback belonging to the InAppBrowser plugin. Care has been + * taken that other callbacks cannot be triggered, and that no other code + * execution is possible. + * + * To trigger the bridge, the prompt default value should be of the form: + * + * gap-iab:// + * + * where is the string id of the callback to trigger (something + * like "InAppBrowser0123456789") + * + * If present, the prompt message is expected to be a JSON-encoded value to + * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid. + * + * @param view + * @param url + * @param message + * @param defaultValue + * @param result + */ + @Override + public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { + // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute. + if (defaultValue != null && defaultValue.startsWith("gap")) { + if(defaultValue.startsWith("gap-iab://")) { + PluginResult scriptResult; + String scriptCallbackId = defaultValue.substring(10); + if (scriptCallbackId.startsWith("InAppBrowser")) { + if(message == null || message.length() == 0) { + scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray()); + } else { + try { + scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message)); + } catch(JSONException e) { + scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()); + } + } + this.webView.sendPluginResult(scriptResult, scriptCallbackId); + result.confirm(""); + return true; + } + } + else + { + // Anything else with a gap: prefix should get this message + LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue); + result.cancel(); + return true; + } + } + return false; + } + +}