Fixed HttpAuthCredentialDatabase.removeHttpAuthCredential on Android, Fixed some cases where takeScreenshot was not working on Android, fix #390, Updated HttpAuthCredentialDatabase.getAllAuthCredentials method return type

This commit is contained in:
Lorenzo Pichilli 2020-06-20 21:58:29 +02:00
parent 64246d84d9
commit 9743687ede
11 changed files with 83 additions and 25 deletions

View File

@ -18,6 +18,9 @@
- Fixed error caused by `pauseTimers` on iOS when the WebView has been disposed
- Fixed `ignoresViewportScaleLimits`, `dataDetectorTypes`, `suppressesIncrementalRendering`, `selectionGranularity` iOS-specific option when used in `initialOptions`
- Fixed `getFavicons` method
- Fixed `HttpAuthCredentialDatabase.removeHttpAuthCredential` on Android
- Fixed some cases where `takeScreenshot` was not working on Android
- Fixed `After upgrade to Android embedding V2, still get Shared.activity is null / NullPointerException on android.content.Context.getResources()` [#390](https://github.com/pichillilorenzo/flutter_inappwebview/issues/390)
### BREAKING CHANGES
@ -27,6 +30,7 @@
- `builtInZoomControls` android webview options changed default value to `true`
- Updated `ServerTrustChallenge` class used by the `onReceivedServerTrustAuthRequest` event
- The method `getOptions` could return null now
- Updated `HttpAuthCredentialDatabase.getAllAuthCredentials` method return type
## 3.3.0+3

View File

@ -495,7 +495,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `useOnDownloadStart`: Set to `true` to be able to listen at the `onDownloadStart` event. The default value is `false`.
* `useShouldInterceptAjaxRequest`: Set to `true` to be able to listen at the `shouldInterceptAjaxRequest` event. The default value is `false`.
* `useShouldInterceptFetchRequest`: Set to `true` to be able to listen at the `shouldInterceptFetchRequest` event. The default value is `false`.
* `clearCache`: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
* `clearCache`: Set to `true` to have all the browser's cache cleared before the new WebView is opened. The default value is `false`.
* `userAgent`: Sets the user-agent for the WebView.
* `applicationNameForUserAgent`: Append to the existing user-agent. Setting userAgent will override this.
* `javaScriptEnabled`: Set to `true` to enable JavaScript. The default value is `true`.

View File

@ -57,7 +57,8 @@ public class CredentialDatabase {
public void removeHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
if (protectionSpace != null) {
credentialDao.find(username, password, protectionSpace.id);
Credential credential = credentialDao.find(username, password, protectionSpace.id);
credentialDao.delete(credential);
}
}

View File

@ -1,6 +1,7 @@
package com.pichillilorenzo.flutter_inappwebview;
import android.os.Build;
import android.webkit.WebViewDatabase;
import androidx.annotation.RequiresApi;
@ -108,6 +109,7 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
break;
case "clearAllAuthCredentials":
credentialDatabase.clearAllAuthCredentials();
WebViewDatabase.getInstance(Shared.applicationContext).clearHttpAuthUsernamePassword();
result.success(true);
break;
default:

View File

@ -1056,10 +1056,20 @@ final public class InAppWebView extends InputAwareWebView {
Canvas c = new Canvas(b);
draw(c);
int scrollOffset = (getScrollY() + getMeasuredHeight() > b.getHeight())
? b.getHeight() : getScrollY();
int scrollY = getScrollY();
int measuredHeight = getMeasuredHeight();
int bitmapHeight = b.getHeight();
int scrollOffset = (scrollY + measuredHeight > bitmapHeight)
? (bitmapHeight - measuredHeight) : scrollY;
if (scrollOffset < 0) {
scrollOffset = 0;
}
Bitmap resized = Bitmap.createBitmap(
b, 0, scrollOffset, b.getWidth(), getMeasuredHeight());
b, 0, scrollOffset, b.getWidth(), measuredHeight);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
@ -1610,6 +1620,7 @@ final public class InAppWebView extends InputAwareWebView {
InputMethodManager imm =
(InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
if (imm != null && !imm.isAcceptingText()) {
imm.hideSoftInputFromWindow(
containerView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

View File

@ -224,10 +224,6 @@ public class InAppWebViewClient extends WebViewClient {
CookieSyncManager.getInstance().sync();
}
// https://issues.apache.org/jira/browse/CB-11248
view.clearFocus();
view.requestFocus();
String js = InAppWebView.platformReadyJS.replaceAll("[\r\n]+", "");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

View File

@ -15,6 +15,7 @@ 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.FlutterMain;
import io.flutter.view.FlutterView;
public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
@ -34,6 +35,8 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
public InAppWebViewFlutterPlugin() {}
public static void registerWith(PluginRegistry.Registrar registrar) {
Log.d(LOG_TAG, "\n\n\nregisterWith\n\n\n");
final InAppWebViewFlutterPlugin instance = new InAppWebViewFlutterPlugin();
Shared.registrar = registrar;
instance.onAttachedToEngine(
@ -43,11 +46,17 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
Shared.flutterAssets = binding.getFlutterAssets();
// Shared.activity could be null or not.
// It depends on who is called first between onAttachedToEngine event and onAttachedToActivity event.
//
// See https://github.com/pichillilorenzo/flutter_inappwebview/issues/390#issuecomment-647039084
onAttachedToEngine(
binding.getApplicationContext(), binding.getBinaryMessenger(), null, binding.getPlatformViewRegistry(), null);
binding.getApplicationContext(), binding.getBinaryMessenger(), Shared.activity, binding.getPlatformViewRegistry(), null);
}
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
Shared.applicationContext = applicationContext;
Shared.activity = activity;
Shared.messenger = messenger;

View File

@ -2962,4 +2962,12 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
deinit {
print("InAppWebView - dealloc")
}
// var accessoryView: UIView?
//
// // https://stackoverflow.com/a/58001395/4637638
// public override var inputAccessoryView: UIView? {
// // remove/replace the default accessory view
// return accessoryView
// }
}

View File

@ -31,26 +31,30 @@ class HttpAuthCredentialDatabase {
///Gets a map list of all HTTP auth credentials saved.
///Each map contains the key `protectionSpace` of type [ProtectionSpace]
///and the key `credentials` of type `List<HttpAuthCredential>` that contains all the HTTP auth credentials saved for that `protectionSpace`.
Future<List<Map<String, dynamic>>> getAllAuthCredentials() async {
Future<List<ProtectionSpaceHttpAuthCredentials>> getAllAuthCredentials() async {
Map<String, dynamic> args = <String, dynamic>{};
List<dynamic> allCredentials =
await _channel.invokeMethod('getAllAuthCredentials', args);
List<Map<String, dynamic>> result = [];
List<ProtectionSpaceHttpAuthCredentials> result = [];
for (Map<dynamic, dynamic> map in allCredentials) {
Map<dynamic, dynamic> protectionSpace = map["protectionSpace"];
List<dynamic> credentials = map["credentials"];
result.add({
"protectionSpace": ProtectionSpace(
host: protectionSpace["host"],
protocol: protectionSpace["protocol"],
realm: protectionSpace["realm"],
port: protectionSpace["port"]),
"credentials": credentials
.map((credential) => HttpAuthCredential(
username: credential["username"],
password: credential["password"]))
.toList()
});
result.add(
ProtectionSpaceHttpAuthCredentials(
protectionSpace: ProtectionSpace(
host: protectionSpace["host"],
protocol: protectionSpace["protocol"],
realm: protectionSpace["realm"],
port: protectionSpace["port"]),
credentials: credentials
.map((credential) => HttpAuthCredential(
username: credential["username"],
password: credential["password"]))
.toList()
)
);
}
return result;
}

View File

@ -874,6 +874,29 @@ class HttpAuthCredential {
}
}
class ProtectionSpaceHttpAuthCredentials {
ProtectionSpace protectionSpace;
List<HttpAuthCredential> credentials;
ProtectionSpaceHttpAuthCredentials({this.protectionSpace, this.credentials});
Map<String, dynamic> toMap() {
return {
"protectionSpace": protectionSpace?.toMap(),
"credentials": credentials?.map((credential) => credential?.toMap())?.toList()
};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///Class used by [ServerTrustAuthResponse] class.
class ServerTrustAuthResponseAction {
final int _value;

View File

@ -89,7 +89,7 @@ class InAppWebViewOptions
///Set to `true` to be able to listen at the [onDownloadStart] event. The default value is `false`.
bool useOnDownloadStart;
///Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
///Set to `true` to have all the browser's cache cleared before the new WebView is opened. The default value is `false`.
bool clearCache;
///Sets the user-agent for the WebView.