Skip to content

[webview_flutter_android] Adds internal wrapper methods for native WebViewClient. #8964

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.3.5

* Adds internal wrapper methods for native `WebViewClient`.

## 4.3.4

* Bumps gradle from 8.0.0 to 8.9.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ android {
implementation 'androidx.annotation:annotation:1.9.1'
implementation 'androidx.webkit:webkit:1.12.1'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.16.1'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was required for me to run tests locally. I'm not sure if this is just me or not.

testImplementation 'org.mockito:mockito-inline:5.1.0'
testImplementation 'androidx.test:core:1.4.0'
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.webkit.ClientCertRequest;
import androidx.annotation.NonNull;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;

/**
* ProxyApi implementation for {@link ClientCertRequest}. This class may handle instantiating native
* object instances that are attached to a Dart instance or handle method calls on the associated
* native class or an instance of that class.
*/
class ClientCertRequestProxyApi extends PigeonApiClientCertRequest {
ClientCertRequestProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@Override
public void cancel(@NonNull ClientCertRequest pigeon_instance) {
pigeon_instance.cancel();
}

@Override
public void ignore(@NonNull ClientCertRequest pigeon_instance) {
pigeon_instance.ignore();
}

@Override
public void proceed(
@NonNull ClientCertRequest pigeon_instance,
@NonNull PrivateKey privateKey,
@NonNull List<? extends X509Certificate> chain) {
pigeon_instance.proceed(privateKey, chain.toArray(new X509Certificate[0]));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.os.Message;
import androidx.annotation.NonNull;

/**
* Proxy API implementation for `Message`.
*
* <p>This class may handle instantiating and adding native object instances that are attached to a
* Dart instance or handle method calls on the associated native class or an instance of the class.
*/
public class MessageProxyApi extends PigeonApiAndroidMessage {
public MessageProxyApi(@NonNull AndroidWebkitLibraryPigeonProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@Override
public void sendToTarget(@NonNull Message pigeon_instance) {
pigeon_instance.sendToTarget();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ void logError(String tag, Throwable exception) {
+ Log.getStackTraceString(exception));
}

/** Creates an exception when the `unknown` enum value is passed to a host method. */
@NonNull
IllegalArgumentException createUnknownEnumException(@NonNull Object enumValue) {
return new IllegalArgumentException(enumValue + " doesn't represent a native value.");
}

/** Creates the error message when a method is called on an unsupported version. */
@NonNull
String createUnsupportedVersionMessage(
@NonNull String method, @NonNull String versionRequirements) {
return method + " requires " + versionRequirements + ".";
}

@NonNull
@Override
public PigeonApiWebResourceRequest getPigeonApiWebResourceRequest() {
Expand Down Expand Up @@ -183,6 +196,42 @@ public PigeonApiHttpAuthHandler getPigeonApiHttpAuthHandler() {
return new HttpAuthHandlerProxyApi(this);
}

@NonNull
@Override
public PigeonApiClientCertRequest getPigeonApiClientCertRequest() {
return new ClientCertRequestProxyApi(this);
}

@NonNull
@Override
public PigeonApiSslErrorHandler getPigeonApiSslErrorHandler() {
return new SslErrorHandlerProxyApi(this);
}

@NonNull
@Override
public PigeonApiSslError getPigeonApiSslError() {
return new SslErrorProxyApi(this);
}

@NonNull
@Override
public PigeonApiSslCertificateDName getPigeonApiSslCertificateDName() {
return new SslCertificateDNameProxyApi(this);
}

@NonNull
@Override
public PigeonApiSslCertificate getPigeonApiSslCertificate() {
return new SslCertificateProxyApi(this);
}

@NonNull
@Override
public PigeonApiAndroidMessage getPigeonApiAndroidMessage() {
return new MessageProxyApi(this);
}

@NonNull
public Context getContext() {
return context;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.net.http.SslCertificate;
import androidx.annotation.NonNull;

/**
* ProxyApi implementation for {@link SslCertificate.DName}. This class may handle instantiating
* native object instances that are attached to a Dart instance or handle method calls on the
* associated native class or an instance of that class.
*/
class SslCertificateDNameProxyApi extends PigeonApiSslCertificateDName {
SslCertificateDNameProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@NonNull
@Override
public String getCName(@NonNull SslCertificate.DName pigeon_instance) {
return pigeon_instance.getCName();
}

@NonNull
@Override
public String getDName(@NonNull SslCertificate.DName pigeon_instance) {
return pigeon_instance.getDName();
}

@NonNull
@Override
public String getOName(@NonNull SslCertificate.DName pigeon_instance) {
return pigeon_instance.getOName();
}

@NonNull
@Override
public String getUName(@NonNull SslCertificate.DName pigeon_instance) {
return pigeon_instance.getUName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.net.http.SslCertificate;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Date;

/**
* ProxyApi implementation for {@link SslCertificate}. This class may handle instantiating native
* object instances that are attached to a Dart instance or handle method calls on the associated
* native class or an instance of that class.
*/
class SslCertificateProxyApi extends PigeonApiSslCertificate {
SslCertificateProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@NonNull
@Override
public ProxyApiRegistrar getPigeonRegistrar() {
return (ProxyApiRegistrar) super.getPigeonRegistrar();
}

@Nullable
@Override
public android.net.http.SslCertificate.DName getIssuedBy(
@NonNull SslCertificate pigeon_instance) {
return pigeon_instance.getIssuedBy();
}

@Nullable
@Override
public android.net.http.SslCertificate.DName getIssuedTo(
@NonNull SslCertificate pigeon_instance) {
return pigeon_instance.getIssuedTo();
}

@Nullable
@Override
public Long getValidNotAfterMsSinceEpoch(@NonNull SslCertificate pigeon_instance) {
final Date date = pigeon_instance.getValidNotAfterDate();
if (date != null) {
return date.getTime();
}
return null;
}

@Nullable
@Override
public Long getValidNotBeforeMsSinceEpoch(@NonNull SslCertificate pigeon_instance) {
final Date date = pigeon_instance.getValidNotBeforeDate();
if (date != null) {
return date.getTime();
}
return null;
}

@Nullable
@Override
public java.security.cert.X509Certificate getX509Certificate(
@NonNull SslCertificate pigeon_instance) {
if (getPigeonRegistrar().sdkIsAtLeast(Build.VERSION_CODES.Q)) {
return pigeon_instance.getX509Certificate();
} else {
Log.d(
"SslCertificateProxyApi",
getPigeonRegistrar()
.createUnsupportedVersionMessage(
"SslCertificate.getX509Certificate", "Build.VERSION_CODES.Q"));
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.webkit.SslErrorHandler;
import androidx.annotation.NonNull;

/**
* ProxyApi implementation for {@link SslErrorHandler}. This class may handle instantiating native
* object instances that are attached to a Dart instance or handle method calls on the associated
* native class or an instance of that class.
*/
class SslErrorHandlerProxyApi extends PigeonApiSslErrorHandler {
SslErrorHandlerProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@Override
public void cancel(@NonNull SslErrorHandler pigeon_instance) {
pigeon_instance.cancel();
}

@Override
public void proceed(@NonNull SslErrorHandler pigeon_instance) {
pigeon_instance.proceed();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import android.net.http.SslError;
import androidx.annotation.NonNull;

/**
* ProxyApi implementation for {@link SslError}. This class may handle instantiating native object
* instances that are attached to a Dart instance or handle method calls on the associated native
* class or an instance of that class.
*/
class SslErrorProxyApi extends PigeonApiSslError {
SslErrorProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
super(pigeonRegistrar);
}

@NonNull
@Override
public ProxyApiRegistrar getPigeonRegistrar() {
return (ProxyApiRegistrar) super.getPigeonRegistrar();
}

@NonNull
@Override
public android.net.http.SslCertificate certificate(@NonNull SslError pigeon_instance) {
return pigeon_instance.getCertificate();
}

@NonNull
@Override
public String url(@NonNull SslError pigeon_instance) {
return pigeon_instance.getUrl();
}

@NonNull
@Override
public SslErrorType getPrimaryError(@NonNull SslError pigeon_instance) {
switch (pigeon_instance.getPrimaryError()) {
case SslError.SSL_DATE_INVALID:
return SslErrorType.DATE_INVALID;
case SslError.SSL_EXPIRED:
return SslErrorType.EXPIRED;
case SslError.SSL_IDMISMATCH:
return SslErrorType.ID_MISMATCH;
case SslError.SSL_INVALID:
return SslErrorType.INVALID;
case SslError.SSL_NOTYETVALID:
return SslErrorType.NOT_YET_VALID;
case SslError.SSL_UNTRUSTED:
return SslErrorType.UNTRUSTED;
default:
return SslErrorType.UNKNOWN;
}
}

@Override
public boolean hasError(@NonNull SslError pigeon_instance, @NonNull SslErrorType error) {
int nativeError = -1;
switch (error) {
case DATE_INVALID:
nativeError = SslError.SSL_DATE_INVALID;
break;
case EXPIRED:
nativeError = SslError.SSL_EXPIRED;
break;
case ID_MISMATCH:
nativeError = SslError.SSL_IDMISMATCH;
break;
case INVALID:
nativeError = SslError.SSL_INVALID;
break;
case NOT_YET_VALID:
nativeError = SslError.SSL_NOTYETVALID;
break;
case UNTRUSTED:
nativeError = SslError.SSL_UNTRUSTED;
break;
case UNKNOWN:
throw getPigeonRegistrar().createUnknownEnumException(error);
}
return pigeon_instance.hasError(nativeError);
}
}
Loading