Commit 5e272c46 authored by Lorenzo Pichilli's avatar Lorenzo Pichilli

fix #182, updated java classes for Flutter 1.12 new Java Embedding API (Android)

parent 63f77cf1
This diff is collapsed.
## 2.2.0
## 3.0.0
- Updated for Flutter 1.12 new Java Embedding API (Android)
- Updated `clearCache` for Android
- Added `Promise` javascript [polyfill](https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js) for webviews that doesn't support it for `window.flutter_inappwebview.callHandler`
- Added `getDefaultUserAgent` static method to `InAppWebViewController`
......@@ -11,6 +12,7 @@
- Fix for Android `InAppBrowser` for some controller methods not exposed.
- Merge "Fixes null error when calling getOptions for InAppBrowser class" [#214](https://github.com/pichillilorenzo/flutter_inappwebview/pull/214) (thanks to [panndoraBoo](https://github.com/panndoraBoo))
- Added `dropDownWorkaroundEnabled` webview option for Android to enable a temporary workaround for html dropdowns (issue [#182](https://github.com/pichillilorenzo/flutter_inappwebview/issues/182))
- Fixed "App Crashes after clicking on dropdown (Using inappwebview)" [#182](https://github.com/pichillilorenzo/flutter_inappwebview/issues/182)
### BREAKING CHANGES
......
......@@ -13,11 +13,13 @@ A Flutter plugin that allows you to add an inline webview or open an in-app brow
- Dart sdk: ">=2.0.0-dev.68.0 <3.0.0"
- Flutter: ">=1.9.1+hotfix.5 <2.0.0"
- Android: `minSdkVersion 17`
- Android: `minSdkVersion 17` and add support for `androidx` (see [AndroidX Migration](https://flutter.dev/docs/development/androidx-migration) to migrate an existing app)
- iOS: `--ios-language swift`, Xcode version `>= 11`
### IMPORTANT Note for Android
If you are starting a new fresh app, you need to create the Flutter App with `flutter create --androidx -i swift` to add support for `androidx`, otherwise it won't work (see [AndroidX Migration](https://flutter.dev/docs/development/androidx-migration) to migrate an existing app).
During the build, if Android fails with `Error: uses-sdk:minSdkVersion 16 cannot be smaller than version 17 declared in library`, it means that you need to update the `minSdkVersion` of your `android/app/build.gradle` file to at least `17`.
Also, you need to add `<uses-permission android:name="android.permission.INTERNET"/>` in the `android/app/src/main/AndroidManifest.xml` file in order to give minimum permission to perform network operations in your application.
......@@ -26,7 +28,7 @@ Because of [Flutter AndroidX compatibility](https://flutter.dev/docs/development
### IMPORTANT Note for iOS
If you are starting a new fresh app, you need to create the Flutter App with `flutter create -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
If you are starting a new fresh app, you need to create the Flutter App with `flutter create --androidx -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
```
=== BUILD TARGET flutter_inappwebview OF PROJECT Pods WITH CONFIGURATION Debug ===
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2, 5.0. This setting can be set in the build settings editor.
......@@ -410,7 +412,6 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `hardwareAcceleration`: Boolean value to enable Hardware Acceleration in the WebView.
* `supportMultipleWindows`: Sets whether the WebView whether supports multiple windows.
* `regexToCancelSubFramesLoading`: Regular expression used by `shouldOverrideUrlLoading` event to cancel navigation for frames that are not the main frame. If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
* `dropDownWorkaroundEnabled`: Enable a temporary workaround for html dropdowns (`<select>` tags) (available on Android 19+). It requires **JavaScript enabled**. It attempts to block click events for the dropdowns creating a custom `<div>` layer over the dropdown to intercept user's clicks. This workaround is applied as soon as the web page fires the `DOMContentLoaded` JavaScript event. The default value is `false`.
##### `InAppWebView` iOS-specific options
......
......@@ -13,6 +13,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
......@@ -22,15 +23,13 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
static final String LOG_TAG = "CredentialDatabaseHandler";
public static PluginRegistry.Registrar registrar;
public static MethodChannel channel;
public static CredentialDatabase credentialDatabase;
public CredentialDatabaseHandler(PluginRegistry.Registrar r) {
registrar = r;
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_credential_database");
public CredentialDatabaseHandler(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_credential_database");
channel.setMethodCallHandler(this);
credentialDatabase = CredentialDatabase.getInstance(registrar.context());
credentialDatabase = CredentialDatabase.getInstance(Shared.applicationContext);
}
@Override
......
......@@ -5,6 +5,7 @@ import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
......@@ -15,10 +16,12 @@ import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebViewOptions;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;
......@@ -31,15 +34,10 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
static final String LOG_TAG = "FlutterWebView";
public final Activity activity;
public InAppWebView webView;
public final MethodChannel channel;
public final Registrar registrar;
public FlutterWebView(Registrar registrar, final Context context, int id, HashMap<String, Object> params, View containerView) {
this.registrar = registrar;
this.activity = registrar.activity();
public FlutterWebView(BinaryMessenger messenger, final Context context, int id, HashMap<String, Object> params, View containerView) {
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
displayListenerProxy.onPreWebViewInitialization(displayManager);
......@@ -53,17 +51,31 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
InAppWebViewOptions options = new InAppWebViewOptions();
options.parse(initialOptions);
webView = new InAppWebView(registrar, context, this, id, options, containerView);
webView = new InAppWebView(Shared.activity, this, id, options, containerView);
displayListenerProxy.onPostWebViewInitialization(displayManager);
// fix https://github.com/pichillilorenzo/flutter_inappwebview/issues/182
try {
Class superClass = webView.getClass().getSuperclass();
while(!superClass.getName().equals("android.view.View")) {
superClass = superClass.getSuperclass();
}
Field mContext = superClass.getDeclaredField("mContext");
mContext.setAccessible(true);
mContext.set(webView, context);
} catch (Exception e) {
e.printStackTrace();
Log.e(LOG_TAG, "Cannot find mContext for this WebView");
}
webView.prepare();
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_" + id);
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
if (initialFile != null) {
try {
initialUrl = Util.getUrlAsset(registrar, initialFile);
initialUrl = Util.getUrlAsset(initialFile);
} catch (IOException e) {
e.printStackTrace();
Log.e(LOG_TAG, initialFile + " asset file cannot be found!", e);
......@@ -375,12 +387,17 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
webView.unlockInputConnection();
}
@Override
public void onFlutterViewAttached(View flutterView) {
webView.setContainerView(flutterView);
if (webView != null) {
webView.setContainerView(flutterView);
}
}
@Override
public void onFlutterViewDetached() {
webView.setContainerView(null);
if (webView != null) {
webView.setContainerView(null);
}
}
}
\ No newline at end of file
......@@ -5,25 +5,26 @@ import android.view.View;
import java.util.HashMap;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class FlutterWebViewFactory extends PlatformViewFactory {
private final Registrar registrar;
private final View containerView;
private final BinaryMessenger messenger;
public FlutterWebViewFactory(Registrar registrar, View containerView) {
public FlutterWebViewFactory(BinaryMessenger messenger, View containerView) {
super(StandardMessageCodec.INSTANCE);
this.registrar = registrar;
this.containerView = containerView;
this.messenger = messenger;
}
@Override
public PlatformView create(Context context, int id, Object args) {
HashMap<String, Object> params = (HashMap<String, Object>) args;
return new FlutterWebView(registrar, context, id, params, containerView);
return new FlutterWebView(messenger, context, id, params, containerView);
}
}
......@@ -22,6 +22,7 @@
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
......@@ -47,6 +48,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.Result;
......@@ -57,16 +59,14 @@ import io.flutter.plugin.common.PluginRegistry.Registrar;
*/
public class InAppBrowser implements MethodChannel.MethodCallHandler {
public Registrar registrar;
public MethodChannel channel;
public Map<String, InAppBrowserActivity> webViewActivities = new HashMap<>();
public Map<String, ChromeCustomTabsActivity> chromeCustomTabsActivities = new HashMap<>();
protected static final String LOG_TAG = "IABFlutterPlugin";
public InAppBrowser(Registrar r) {
registrar = r;
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
public InAppBrowser(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappbrowser");
channel.setMethodCallHandler(this);
}
......@@ -74,7 +74,7 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
public void onMethodCall(final MethodCall call, final Result result) {
String source;
String urlFile;
final Activity activity = registrar.activity();
final Activity activity = Shared.activity;
final String uuid = (String) call.argument("uuid");
switch (call.method) {
......@@ -114,7 +114,7 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
if (isLocalFile) {
// check if the asset file exists
try {
url = Util.getUrlAsset(registrar, url);
url = Util.getUrlAsset(url);
} catch (IOException e) {
e.printStackTrace();
result.error(LOG_TAG, url + " asset file cannot be found!", e);
......
......@@ -58,7 +58,6 @@ public class InAppBrowserActivity extends AppCompatActivity {
webView = findViewById(R.id.webView);
webView.inAppBrowserActivity = this;
webView.registrar = InAppWebViewFlutterPlugin.inAppBrowser.registrar;
Bundle b = getIntent().getExtras();
uuid = b.getString("uuid");
......
......@@ -2,6 +2,7 @@ package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
import android.annotation.TargetApi;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
......@@ -31,6 +32,8 @@ import com.pichillilorenzo.flutter_inappwebview.FlutterWebView;
import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -47,7 +50,6 @@ import static android.app.Activity.RESULT_OK;
public class InAppWebViewChromeClient extends WebChromeClient implements PluginRegistry.ActivityResultListener {
protected static final String LOG_TAG = "IABWebChromeClient";
private PluginRegistry.Registrar registrar;
private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity;
private ValueCallback<Uri> mUploadMessage;
......@@ -58,30 +60,31 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
public InAppWebViewChromeClient(Object obj, PluginRegistry.Registrar registrar) {
super();
this.registrar = registrar;
public InAppWebViewChromeClient(Object obj) {
if (obj instanceof InAppBrowserActivity)
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj;
registrar.addActivityResultListener(this);
if (Shared.registrar != null)
Shared.registrar.addActivityResultListener(this);
else
Shared.activityPluginBinding.addActivityResultListener(this);
}
public Bitmap getDefaultVideoPoster() {
if (mCustomView == null) {
return null;
}
return BitmapFactory.decodeResource(this.registrar.activeContext().getResources(), 2130837573);
return BitmapFactory.decodeResource(Shared.activity.getApplicationContext().getResources(), 2130837573);
}
public void onHideCustomView() {
View decorView = this.registrar.activity().getWindow().getDecorView();
View decorView = Shared.activity.getWindow().getDecorView();
((FrameLayout) decorView).removeView(this.mCustomView);
this.mCustomView = null;
decorView.setSystemUiVisibility(this.mOriginalSystemUiVisibility);
this.registrar.activity().setRequestedOrientation(this.mOriginalOrientation);
Shared.activity.setRequestedOrientation(this.mOriginalOrientation);
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
}
......@@ -91,10 +94,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
onHideCustomView();
return;
}
View decorView = this.registrar.activity().getWindow().getDecorView();
View decorView = Shared.activity.getWindow().getDecorView();
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility = decorView.getSystemUiVisibility();
this.mOriginalOrientation = this.registrar.activity().getRequestedOrientation();
this.mOriginalOrientation = Shared.activity.getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;
this.mCustomView.setBackgroundColor(Color.parseColor("#000000"));
((FrameLayout) decorView).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
......@@ -173,7 +176,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(registrar.activeContext(), R.style.Theme_AppCompat_Dialog_Alert);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Shared.activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
if (confirmButtonTitle != null && !confirmButtonTitle.isEmpty()) {
alertDialogBuilder.setPositiveButton(confirmButtonTitle, clickListener);
......@@ -264,7 +267,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(registrar.activeContext(), R.style.Theme_AppCompat_Dialog_Alert);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Shared.activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
if (confirmButtonTitle != null && !confirmButtonTitle.isEmpty()) {
alertDialogBuilder.setPositiveButton(confirmButtonTitle, confirmClickListener);
......@@ -381,7 +384,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(registrar.activeContext(), R.style.Theme_AppCompat_Dialog_Alert);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Shared.activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
if (confirmButtonTitle != null && !confirmButtonTitle.isEmpty()) {
alertDialogBuilder.setPositiveButton(confirmButtonTitle, confirmClickListener);
......@@ -530,7 +533,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
Shared.activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
......@@ -540,7 +543,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(
Shared.activity.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
......@@ -551,7 +554,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
Shared.activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
......@@ -569,7 +572,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
Shared.activity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
return false;
......
......@@ -180,9 +180,6 @@ public class InAppWebViewClient extends WebViewClient {
if (webView.options.useOnLoadResource) {
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
}
if (webView.options.dropDownWorkaroundEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
js += InAppWebView.dropDownWorkaroundJS.replaceAll("[\r\n]+", "");
}
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
......@@ -540,7 +537,7 @@ public class InAppWebViewClient extends WebViewClient {
String certificatePath = (String) responseMap.get("certificatePath");
String certificatePassword = (String) responseMap.get("certificatePassword");
String androidKeyStoreType = (String) responseMap.get("androidKeyStoreType");
Util.PrivateKeyAndCertificates privateKeyAndCertificates = Util.loadPrivateKeyAndCertificate(webView.registrar, certificatePath, certificatePassword, androidKeyStoreType);
Util.PrivateKeyAndCertificates privateKeyAndCertificates = Util.loadPrivateKeyAndCertificate(certificatePath, certificatePassword, androidKeyStoreType);
request.proceed(privateKeyAndCertificates.privateKey, privateKeyAndCertificates.certificates);
}
return;
......
......@@ -83,7 +83,6 @@ public class InAppWebViewOptions extends Options {
public Boolean hardwareAcceleration = true;
public Boolean supportMultipleWindows = false;
public String regexToCancelSubFramesLoading;
public Boolean dropDownWorkaroundEnabled = false;
@Override
public Object onParse(Map.Entry<String, Object> pair) {
......
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.webkit.ValueCallback;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.platform.PlatformViewRegistry;
import io.flutter.view.FlutterView;
public class InAppWebViewFlutterPlugin implements FlutterPlugin {
public PluginRegistry.Registrar registrar;
public MethodChannel channel;
public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
protected static final String LOG_TAG = "InAppWebViewFlutterPlugin";
protected static final String LOG_TAG = "InAppWebViewFlutterPL";
public static InAppBrowser inAppBrowser;
public static InAppWebViewStatic inAppWebViewStatic;
......@@ -23,33 +28,32 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
public InAppWebViewFlutterPlugin() {}
public static void registerWith(PluginRegistry.Registrar registrar) {
inAppBrowser = new InAppBrowser(registrar);
registrar
.platformViewRegistry()
.registerViewFactory(
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(registrar, registrar.view()));
new InAppWebViewStatic(registrar);
new MyCookieManager(registrar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
new CredentialDatabaseHandler(registrar);
}
final InAppWebViewFlutterPlugin instance = new InAppWebViewFlutterPlugin();
Shared.registrar = registrar;
instance.onAttachedToEngine(
registrar.context(), registrar.messenger(), registrar.activity(), registrar.platformViewRegistry(), registrar.view());
}
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
//BinaryMessenger messenger = binding.getFlutterEngine().getDartExecutor();
inAppBrowser = new InAppBrowser(registrar);
binding
.getFlutterEngine()
.getPlatformViewsController()
.getRegistry()
.registerViewFactory(
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(registrar,null));
inAppWebViewStatic = new InAppWebViewStatic(registrar);
myCookieManager = new MyCookieManager(registrar);
Shared.flutterAssets = binding.getFlutterAssets();
onAttachedToEngine(
binding.getApplicationContext(), binding.getBinaryMessenger(), null, binding.getPlatformViewRegistry(), null);
}
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
Shared.applicationContext = applicationContext;
Shared.activity = activity;
inAppBrowser = new InAppBrowser(messenger);
platformViewRegistry.registerViewFactory(
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView));
inAppWebViewStatic = new InAppWebViewStatic(messenger);
myCookieManager = new MyCookieManager(messenger);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
credentialDatabaseHandler = new CredentialDatabaseHandler(registrar);
credentialDatabaseHandler = new CredentialDatabaseHandler(messenger);
}
}
......@@ -73,4 +77,28 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
}
uploadMessageArray = null;
}
@Override
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
Shared.activityPluginBinding = activityPluginBinding;
Shared.activity = activityPluginBinding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
Shared.activityPluginBinding = null;
Shared.activity = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
Shared.activityPluginBinding = activityPluginBinding;
Shared.activity = activityPluginBinding.getActivity();
}
@Override
public void onDetachedFromActivity() {
Shared.activityPluginBinding = null;
Shared.activity = null;
}
}
package com.pichillilorenzo.flutter_inappwebview;
import android.util.Log;
import android.webkit.WebSettings;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
public PluginRegistry.Registrar registrar;
public MethodChannel channel;
protected static final String LOG_TAG = "InAppWebViewStatic";
public InAppWebViewStatic(PluginRegistry.Registrar r) {
registrar = r;
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_static");
public InAppWebViewStatic(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_static");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
Log.d(LOG_TAG, call.method);
switch (call.method) {
case "getDefaultUserAgent":
result.success(WebSettings.getDefaultUserAgent(registrar.activeContext()));
result.success(WebSettings.getDefaultUserAgent(Shared.applicationContext));
break;
default:
result.notImplemented();
......
......@@ -290,7 +290,6 @@ public class JavaScriptBridgeInterface {
List<List<String>> values = new ArrayList<>();
JSONArray options = jsonArray.getJSONArray(2);
Log.d(LOG_TAG, options.toString());
for(int i = 0; i < options.length(); i++) {
JSONObject option = options.getJSONObject(i);
......
......@@ -13,6 +13,7 @@ import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
......@@ -21,13 +22,11 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
static final String LOG_TAG = "MyCookieManager";
public static PluginRegistry.Registrar registrar;
public static MethodChannel channel;
public static CookieManager cookieManager;
public MyCookieManager(PluginRegistry.Registrar r) {
registrar = r;
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_cookiemanager");
public MyCookieManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_cookiemanager");
channel.setMethodCallHandler(this);
cookieManager = CookieManager.getInstance();
}
......@@ -110,7 +109,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(registrar.context());
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue);
result.success(true);
......@@ -155,7 +154,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(registrar.context());
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue);
result.success(true);
......@@ -172,7 +171,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
if (cookiesString != null) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
cookieSyncMngr = CookieSyncManager.createInstance(registrar.context());
cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
cookieSyncMngr.startSync();
}
......@@ -208,7 +207,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(registrar.context());
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
cookieSyncMngr.startSync();
cookieManager.removeAllCookie();
result.success(true);
......
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Context;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.PluginRegistry;
public class Shared {
public static Context applicationContext;
public static PluginRegistry.Registrar registrar;
public static FlutterPlugin.FlutterAssets flutterAssets;
public static ActivityPluginBinding activityPluginBinding;
public static Activity activity;
}
......@@ -27,7 +27,6 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import okhttp3.OkHttpClient;
public class Util {
......@@ -37,13 +36,13 @@ public class Util {
private Util() {}
public static String getUrlAsset(PluginRegistry.Registrar registrar, String assetFilePath) throws IOException {
String key = registrar.lookupKeyForAsset(assetFilePath);
public static String getUrlAsset(String assetFilePath) throws IOException {
String key = (Shared.registrar != null) ? Shared.registrar.lookupKeyForAsset(assetFilePath) : Shared.flutterAssets.getAssetFilePathByName(assetFilePath);
InputStream is = null;
IOException e = null;
try {
is = getFileAsset(registrar, assetFilePath);
is = getFileAsset(assetFilePath);
} catch (IOException ex) {
e = ex;
} finally {
......@@ -62,9 +61,9 @@ public class Util {
return ANDROID_ASSET_URL + key;
}
public static InputStream getFileAsset(PluginRegistry.Registrar registrar, String assetFilePath) throws IOException {
String key = registrar.lookupKeyForAsset(assetFilePath);
AssetManager mg = registrar.activeContext().getResources().getAssets();
public static InputStream getFileAsset(String assetFilePath) throws IOException {
String key = (Shared.registrar != null) ? Shared.registrar.lookupKeyForAsset(assetFilePath) : Shared.flutterAssets.getAssetFilePathByName(assetFilePath);
AssetManager mg = Shared.applicationContext.getResources().getAssets();
return mg.open(key);
}
......@@ -116,12 +115,12 @@ public class Util {
}
}
public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate(PluginRegistry.Registrar registrar, String certificatePath, String certificatePassword, String keyStoreType) {
public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate( String certificatePath, String certificatePassword, String keyStoreType) {
PrivateKeyAndCertificates privateKeyAndCertificates = null;
try {
InputStream certificateFileStream = getFileAsset(registrar, certificatePath);
InputStream certificateFileStream = getFileAsset(certificatePath);
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(certificateFileStream, certificatePassword != null ? certificatePassword.toCharArray() : null);
......
......@@ -263,7 +263,7 @@ void main() {
final sideMenuButton = find.byValueKey('SideMenu');
final listTiles = find.byValueKey('ListTiles');
final nextTest = find.byValueKey('InAppWebViewOnTargetBlankTest');
final nextTest = find.byValueKey('InAppWebViewOnCreateWindowTest');
while((await driver.getText(appBarTitle)) == "InAppWebViewOnDownloadStartTest") {
await Future.delayed(const Duration(milliseconds: 500));
......@@ -277,14 +277,14 @@ void main() {
await driver.tap(nextTest);
}, timeout: new Timeout(new Duration(minutes: 5)));
test('InAppWebViewOnTargetBlankTest', () async {
test('InAppWebViewOnCreateWindowTest', () async {
final appBarTitle = find.byValueKey('AppBarTitle');
final sideMenuButton = find.byValueKey('SideMenu');
final listTiles = find.byValueKey('ListTiles');
final nextTest = find.byValueKey('InAppWebViewOnJsDialogTest');
while((await driver.getText(appBarTitle)) == "InAppWebViewOnTargetBlankTest") {
while((await driver.getText(appBarTitle)) == "InAppWebViewOnCreateWindowTest") {
await Future.delayed(const Duration(milliseconds: 500));
}
......
......@@ -26,7 +26,6 @@
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
......
......@@ -408,14 +408,6 @@ class AndroidInAppWebViewOptions
///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
String regexToCancelSubFramesLoading;
///Enable a temporary workaround for html dropdowns (`<select>` tags). It requires **JavaScript enabled**.
///It attempts to block click events for the dropdowns creating a custom `<div>` layer over the dropdown to intercept user's clicks.
///This workaround is applied as soon as the web page fires the `DOMContentLoaded` JavaScript event.
///The default value is `false`.
///
///**NOTE**: available on Android 19+.
bool dropDownWorkaroundEnabled;
AndroidInAppWebViewOptions(
{this.textZoom = 100,
this.clearSessionCache = false,
......@@ -458,8 +450,7 @@ class AndroidInAppWebViewOptions
this.hardwareAcceleration = true,
this.initialScale = 0,
this.supportMultipleWindows = false,
this.regexToCancelSubFramesLoading,
this.dropDownWorkaroundEnabled = false});
this.regexToCancelSubFramesLoading});
@override
Map<String, dynamic> toMap() {
......@@ -505,8 +496,7 @@ class AndroidInAppWebViewOptions
"thirdPartyCookiesEnabled": thirdPartyCookiesEnabled,
"hardwareAcceleration": hardwareAcceleration,
"supportMultipleWindows": supportMultipleWindows,
"regexToCancelSubFramesLoading": regexToCancelSubFramesLoading,
"dropDownWorkaroundEnabled": dropDownWorkaroundEnabled
"regexToCancelSubFramesLoading": regexToCancelSubFramesLoading
};
}
......@@ -561,7 +551,6 @@ class AndroidInAppWebViewOptions
options.hardwareAcceleration = map["hardwareAcceleration"];
options.supportMultipleWindows = map["supportMultipleWindows"];
options.regexToCancelSubFramesLoading = map["regexToCancelSubFramesLoading"];
options.dropDownWorkaroundEnabled = map["dropDownWorkaroundEnabled"];
return options;
}
}
......
......@@ -92,12 +92,9 @@ appAuthBasic.use((req, res, next) => {
} else {
next()
}
})
});
appAuthBasic.use(express.static(__dirname + '/public'));
appAuthBasic.get('/test-index', (req, res) => {
res.sendFile(__dirname + '/public/index.html');
});
appAuthBasic.get("/", (req, res) => {
console.log(JSON.stringify(req.headers))
......@@ -111,9 +108,13 @@ appAuthBasic.get("/", (req, res) => {
</html>
`);
res.end()
})
});
appAuthBasic.listen(8081)
appAuthBasic.get('/test-index', (req, res) => {
res.sendFile(__dirname + '/public/test-index.html');
});
appAuthBasic.listen(8081);
......@@ -126,9 +127,6 @@ app.use(cors());
app.use(express.json());
app.use(express.static(__dirname + '/public'));
app.get('/test-index', (req, res) => {
res.sendFile(__dirname + '/public/index.html');
});
app.get("/", (req, res) => {
console.log(JSON.stringify(req.headers))
......@@ -144,6 +142,10 @@ app.get("/", (req, res) => {
res.end()
})
app.get('/test-index', (req, res) => {
res.sendFile(__dirname + '/public/index.html');
})
app.post("/test-post", (req, res) => {
console.log(JSON.stringify(req.headers))
console.log(JSON.stringify(req.body))
......
name: flutter_inappwebview
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window.
version: 2.2.0
version: 3.0.0
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
flutter: ">=1.9.1+hotfix.5 <2.0.0"
flutter: ">=1.10.0 <2.0.0"
dependencies:
flutter:
......
#!/bin/bash
# on linux/macOS local IP can be found using $(ipconfig getifaddr en0)
export NODE_SERVER_IP=$1
dart tool/env.dart
cd nodejs_server_test_auth_basic_and_ssl
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment