diff options
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java')
| -rw-r--r--[-rwxr-xr-x] | StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java | 294 |
1 files changed, 215 insertions, 79 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java index 60437451..8f4f3d97 100755..100644 --- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java +++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java @@ -19,7 +19,6 @@ package org.apache.cordova.inappbrowser; import android.annotation.SuppressLint; -import org.apache.cordova.inappbrowser.InAppBrowserDialog; import android.content.Context; import android.content.Intent; import android.provider.Browser; @@ -30,7 +29,6 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.InputType; -import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; @@ -41,17 +39,21 @@ import android.view.WindowManager.LayoutParams; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.webkit.CookieManager; +import android.webkit.CookieSyncManager; +import android.webkit.HttpAuthHandler; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; -import android.widget.Button; import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import org.apache.cordova.CallbackContext; import org.apache.cordova.Config; import org.apache.cordova.CordovaArgs; +import org.apache.cordova.CordovaHttpAuthHandler; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CordovaWebView; import org.apache.cordova.LOG; @@ -61,6 +63,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.StringTokenizer; @@ -82,6 +85,8 @@ public class InAppBrowser extends CordovaPlugin { private static final String CLEAR_ALL_CACHE = "clearcache"; private static final String CLEAR_SESSION_CACHE = "clearsessioncache"; private static final String HARDWARE_BACK_BUTTON = "hardwareback"; + private static final String MEDIA_PLAYBACK_REQUIRES_USER_ACTION = "mediaPlaybackRequiresUserAction"; + private static final String SHOULD_PAUSE = "shouldPauseOnSuspend"; private InAppBrowserDialog dialog; private WebView inAppWebView; @@ -93,6 +98,8 @@ public class InAppBrowser extends CordovaPlugin { private boolean clearAllCache = false; private boolean clearSessionCache = false; private boolean hadwareBackButton = true; + private boolean mediaPlaybackRequiresUserGesture = false; + private boolean shouldPauseInAppBrowser = false; /** * Executes the request and returns PluginResult. @@ -113,7 +120,7 @@ public class InAppBrowser extends CordovaPlugin { final String target = t; final HashMap<String, Boolean> features = parseFeature(args.optString(2)); - Log.d(LOG_TAG, "target = " + target); + LOG.d(LOG_TAG, "target = " + target); this.cordova.getActivity().runOnUiThread(new Runnable() { @Override @@ -121,7 +128,7 @@ public class InAppBrowser extends CordovaPlugin { String result = ""; // SELF if (SELF.equals(target)) { - Log.d(LOG_TAG, "in self"); + LOG.d(LOG_TAG, "in self"); /* This code exists for compatibility between 3.x and 4.x versions of Cordova. * Previously the Config class had a static method, isUrlWhitelisted(). That * responsibility has been moved to the plugins, with an aggregating method in @@ -136,8 +143,11 @@ public class InAppBrowser extends CordovaPlugin { Method iuw = Config.class.getMethod("isUrlWhiteListed", String.class); shouldAllowNavigation = (Boolean)iuw.invoke(null, url); } catch (NoSuchMethodException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } catch (IllegalAccessException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } catch (InvocationTargetException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } } if (shouldAllowNavigation == null) { @@ -147,20 +157,23 @@ public class InAppBrowser extends CordovaPlugin { Method san = pm.getClass().getMethod("shouldAllowNavigation", String.class); shouldAllowNavigation = (Boolean)san.invoke(pm, url); } catch (NoSuchMethodException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } catch (IllegalAccessException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } catch (InvocationTargetException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); } } // load in webview if (Boolean.TRUE.equals(shouldAllowNavigation)) { - Log.d(LOG_TAG, "loading in webview"); + LOG.d(LOG_TAG, "loading in webview"); webView.loadUrl(url); } //Load the dialer else if (url.startsWith(WebView.SCHEME_TEL)) { try { - Log.d(LOG_TAG, "loading in dialer"); + LOG.d(LOG_TAG, "loading in dialer"); Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse(url)); cordova.getActivity().startActivity(intent); @@ -170,18 +183,18 @@ public class InAppBrowser extends CordovaPlugin { } // load in InAppBrowser else { - Log.d(LOG_TAG, "loading in InAppBrowser"); + LOG.d(LOG_TAG, "loading in InAppBrowser"); result = showWebPage(url, features); } } // SYSTEM else if (SYSTEM.equals(target)) { - Log.d(LOG_TAG, "in system"); + LOG.d(LOG_TAG, "in system"); result = openExternal(url); } // BLANK - or anything else else { - Log.d(LOG_TAG, "in blank"); + LOG.d(LOG_TAG, "in blank"); result = showWebPage(url, features); } @@ -197,7 +210,7 @@ public class InAppBrowser extends CordovaPlugin { 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()); + jsWrapper = String.format("(function(){prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')})()", callbackContext.getCallbackId()); } injectDeferredObject(args.getString(0), jsWrapper); } @@ -254,6 +267,26 @@ public class InAppBrowser extends CordovaPlugin { } /** + * Called when the system is about to start resuming a previous activity. + */ + @Override + public void onPause(boolean multitasking) { + if (shouldPauseInAppBrowser) { + inAppWebView.onPause(); + } + } + + /** + * Called when the activity will start interacting with the user. + */ + @Override + public void onResume(boolean multitasking) { + if (shouldPauseInAppBrowser) { + inAppWebView.onResume(); + } + } + + /** * Called by AccelBroker when listener is to be shut down. * Stop listener. */ @@ -350,7 +383,7 @@ public class InAppBrowser extends CordovaPlugin { this.cordova.getActivity().startActivity(intent); return ""; } catch (android.content.ActivityNotFoundException e) { - Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString()); + LOG.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString()); return e.toString(); } } @@ -359,20 +392,22 @@ public class InAppBrowser extends CordovaPlugin { * Closes the dialog */ 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() { + final WebView childView = inAppWebView; + // The JS protects against multiple calls, so this should happen only when + // closeDialog() is called by other native code. + if (childView == null) { + return; + } + childView.setWebViewClient(new WebViewClient() { // NB: wait for about:blank before dismissing public void onPageFinished(WebView view, String url) { if (dialog != null) { dialog.dismiss(); + dialog = null; } } }); @@ -380,16 +415,16 @@ public class InAppBrowser extends CordovaPlugin { // other than your app's UI thread, it can cause unexpected results." // http://developer.android.com/guide/webapps/migrating.html#Threads childView.loadUrl("about:blank"); + + try { + JSONObject obj = new JSONObject(); + obj.put("type", EXIT_EVENT); + sendUpdate(obj, false); + } catch (JSONException ex) { + LOG.d(LOG_TAG, "Should never happen"); + } } }); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", EXIT_EVENT); - sendUpdate(obj, false); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } } /** @@ -468,6 +503,8 @@ public class InAppBrowser extends CordovaPlugin { showLocationBar = true; showZoomControls = true; openWindowHidden = false; + mediaPlaybackRequiresUserGesture = false; + if (features != null) { Boolean show = features.get(LOCATION); if (show != null) { @@ -485,6 +522,10 @@ public class InAppBrowser extends CordovaPlugin { if (hardwareBack != null) { hadwareBackButton = hardwareBack.booleanValue(); } + Boolean mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION); + if (mediaPlayback != null) { + mediaPlaybackRequiresUserGesture = mediaPlayback.booleanValue(); + } Boolean cache = features.get(CLEAR_ALL_CACHE); if (cache != null) { clearAllCache = cache.booleanValue(); @@ -494,6 +535,10 @@ public class InAppBrowser extends CordovaPlugin { clearSessionCache = cache.booleanValue(); } } + Boolean shouldPause = features.get(SHOULD_PAUSE); + if (shouldPause != null) { + shouldPauseInAppBrowser = shouldPause.booleanValue(); + } } final CordovaWebView thatWebView = this.webView; @@ -516,6 +561,12 @@ public class InAppBrowser extends CordovaPlugin { @SuppressLint("NewApi") public void run() { + + // CB-6702 InAppBrowser hangs when opening more than one instance + if (dialog != null) { + dialog.dismiss(); + }; + // Let's create the main dialog dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar); dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; @@ -541,26 +592,28 @@ public class InAppBrowser extends CordovaPlugin { actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); actionButtonContainer.setHorizontalGravity(Gravity.LEFT); actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); - actionButtonContainer.setId(1); + actionButtonContainer.setId(Integer.valueOf(1)); // Back button - Button back = new Button(cordova.getActivity()); + ImageButton back = new ImageButton(cordova.getActivity()); RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); back.setLayoutParams(backLayoutParams); back.setContentDescription("Back Button"); - back.setId(2); + back.setId(Integer.valueOf(2)); Resources activityRes = cordova.getActivity().getResources(); int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName()); Drawable backIcon = activityRes.getDrawable(backResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - back.setBackgroundDrawable(backIcon); - } + if (Build.VERSION.SDK_INT >= 16) + back.setBackground(null); else - { - back.setBackground(backIcon); - } + back.setBackgroundDrawable(null); + back.setImageDrawable(backIcon); + back.setScaleType(ImageView.ScaleType.FIT_CENTER); + back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); + if (Build.VERSION.SDK_INT >= 16) + back.getAdjustViewBounds(); + back.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goBack(); @@ -568,22 +621,24 @@ public class InAppBrowser extends CordovaPlugin { }); // Forward button - Button forward = new Button(cordova.getActivity()); + ImageButton forward = new ImageButton(cordova.getActivity()); RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); forward.setLayoutParams(forwardLayoutParams); forward.setContentDescription("Forward Button"); - forward.setId(3); + forward.setId(Integer.valueOf(3)); int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName()); Drawable fwdIcon = activityRes.getDrawable(fwdResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - forward.setBackgroundDrawable(fwdIcon); - } + if (Build.VERSION.SDK_INT >= 16) + forward.setBackground(null); else - { - forward.setBackground(fwdIcon); - } + forward.setBackgroundDrawable(null); + forward.setImageDrawable(fwdIcon); + forward.setScaleType(ImageView.ScaleType.FIT_CENTER); + forward.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); + if (Build.VERSION.SDK_INT >= 16) + forward.getAdjustViewBounds(); + forward.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goForward(); @@ -596,7 +651,7 @@ public class InAppBrowser extends CordovaPlugin { textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); edittext.setLayoutParams(textLayoutParams); - edittext.setId(4); + edittext.setId(Integer.valueOf(4)); edittext.setSingleLine(true); edittext.setText(url); edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI); @@ -614,22 +669,24 @@ public class InAppBrowser extends CordovaPlugin { }); // Close/Done button - Button close = new Button(cordova.getActivity()); + ImageButton close = new ImageButton(cordova.getActivity()); RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); close.setLayoutParams(closeLayoutParams); forward.setContentDescription("Close Button"); - close.setId(5); + close.setId(Integer.valueOf(5)); int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName()); Drawable closeIcon = activityRes.getDrawable(closeResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - close.setBackgroundDrawable(closeIcon); - } + if (Build.VERSION.SDK_INT >= 16) + close.setBackground(null); else - { - close.setBackground(closeIcon); - } + close.setBackgroundDrawable(null); + close.setImageDrawable(closeIcon); + close.setScaleType(ImageView.ScaleType.FIT_CENTER); + back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); + if (Build.VERSION.SDK_INT >= 16) + close.getAdjustViewBounds(); + close.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { closeDialog(); @@ -639,6 +696,7 @@ public class InAppBrowser extends CordovaPlugin { // WebView inAppWebView = new WebView(cordova.getActivity()); inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + inAppWebView.setId(Integer.valueOf(6)); inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView)); WebViewClient client = new InAppBrowserClient(thatWebView, edittext); inAppWebView.setWebViewClient(client); @@ -648,6 +706,20 @@ public class InAppBrowser extends CordovaPlugin { settings.setBuiltInZoomControls(showZoomControls); settings.setPluginState(android.webkit.WebSettings.PluginState.ON); + if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { + settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture); + } + + String overrideUserAgent = preferences.getString("OverrideUserAgent", null); + String appendUserAgent = preferences.getString("AppendUserAgent", null); + + if (overrideUserAgent != null) { + settings.setUserAgentString(overrideUserAgent); + } + if (appendUserAgent != null) { + settings.setUserAgentString(settings.getUserAgentString() + appendUserAgent); + } + //Toggle whether this is enabled or not! Bundle appSettings = cordova.getActivity().getIntent().getExtras(); boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); @@ -665,7 +737,7 @@ public class InAppBrowser extends CordovaPlugin { } inAppWebView.loadUrl(url); - inAppWebView.setId(6); + inAppWebView.setId(Integer.valueOf(6)); inAppWebView.getSettings().setLoadWithOverviewMode(true); inAppWebView.getSettings().setUseWideViewPort(true); inAppWebView.requestFocus(); @@ -753,34 +825,30 @@ public class InAppBrowser extends CordovaPlugin { } /** - * Notify the host application that a page has started loading. + * Override the URL that should be loaded + * + * This handles a small subset of all the URIs that would be encountered. * - * @param view The webview initiating the callback. - * @param url The url of the page. + * @param webView + * @param url */ @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - String newloc = ""; - if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) { - newloc = url; - } - // If dialing phone (tel:5551212) - else if (url.startsWith(WebView.SCHEME_TEL)) { + public boolean shouldOverrideUrlLoading(WebView webView, String url) { + if (url.startsWith(WebView.SCHEME_TEL)) { try { Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse(url)); cordova.getActivity().startActivity(intent); + return true; } catch (android.content.ActivityNotFoundException e) { LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); } - } - - else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:")) { + } else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) { try { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); cordova.getActivity().startActivity(intent); + return true; } catch (android.content.ActivityNotFoundException e) { LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString()); } @@ -795,8 +863,7 @@ public class InAppBrowser extends CordovaPlugin { int parmIndex = url.indexOf('?'); if (parmIndex == -1) { address = url.substring(4); - } - else { + } else { address = url.substring(4, parmIndex); // If body, then set sms body @@ -812,32 +879,64 @@ public class InAppBrowser extends CordovaPlugin { intent.putExtra("address", address); intent.setType("vnd.android-dir/mms-sms"); cordova.getActivity().startActivity(intent); + return true; } catch (android.content.ActivityNotFoundException e) { LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString()); } } - else { + return false; + } + + + /* + * onPageStarted fires the LOAD_START_EVENT + * + * @param view + * @param url + * @param favicon + */ + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + String newloc = ""; + if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) { + newloc = url; + } + else + { + // Assume that everything is HTTP at this point, because if we don't specify, + // it really should be. Complain loudly about this!!! + LOG.e(LOG_TAG, "Possible Uncaught/Unknown URI"); newloc = "http://" + url; } + // Update the UI if we haven't already if (!newloc.equals(edittext.getText().toString())) { edittext.setText(newloc); - } + } try { JSONObject obj = new JSONObject(); obj.put("type", LOAD_START_EVENT); obj.put("url", newloc); - sendUpdate(obj, true); } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); + LOG.e(LOG_TAG, "URI passed in has caused a JSON error."); } } + + public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); + // CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + CookieManager.getInstance().flush(); + } else { + CookieSyncManager.getInstance().sync(); + } + try { JSONObject obj = new JSONObject(); obj.put("type", LOAD_STOP_EVENT); @@ -845,7 +944,7 @@ public class InAppBrowser extends CordovaPlugin { sendUpdate(obj, true); } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); + LOG.d(LOG_TAG, "Should never happen"); } } @@ -861,9 +960,46 @@ public class InAppBrowser extends CordovaPlugin { sendUpdate(obj, true, PluginResult.Status.ERROR); } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); + LOG.d(LOG_TAG, "Should never happen"); } } + + /** + * On received http auth request. + */ + @Override + public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { + + // Check if there is some plugin which can resolve this auth challenge + PluginManager pluginManager = null; + try { + Method gpm = webView.getClass().getMethod("getPluginManager"); + pluginManager = (PluginManager)gpm.invoke(webView); + } catch (NoSuchMethodException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + } catch (IllegalAccessException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + } catch (InvocationTargetException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + } + + if (pluginManager == null) { + try { + Field pmf = webView.getClass().getField("pluginManager"); + pluginManager = (PluginManager)pmf.get(webView); + } catch (NoSuchFieldException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + } catch (IllegalAccessException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + } + } + + if (pluginManager != null && pluginManager.onReceivedHttpAuthRequest(webView, new CordovaHttpAuthHandler(handler), host, realm)) { + return; + } + + // By default handle 401 like we'd normally do! + super.onReceivedHttpAuthRequest(view, handler, host, realm); + } } } - |
