Skip to content

Commit 4389067

Browse files
[webview_flutter_android] Adds internal wrapper methods for native WebViewClient. (#8964)
This adds the SSL classes for #7893 and a few extra `WebViewClient` methods. ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 7bdffbe commit 4389067

34 files changed

+6253
-3013
lines changed

packages/webview_flutter/webview_flutter_android/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 4.3.5
2+
3+
* Adds internal wrapper methods for native `WebViewClient`.
4+
15
## 4.3.4
26

37
* Bumps gradle from 8.0.0 to 8.9.0.

packages/webview_flutter/webview_flutter_android/android/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ android {
5252
implementation 'androidx.annotation:annotation:1.9.1'
5353
implementation 'androidx.webkit:webkit:1.12.1'
5454
testImplementation 'junit:junit:4.13.2'
55+
testImplementation 'org.mockito:mockito-core:5.16.1'
5556
testImplementation 'org.mockito:mockito-inline:5.1.0'
5657
testImplementation 'androidx.test:core:1.4.0'
5758
}

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt

+1,689-491
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.webkit.ClientCertRequest;
8+
import androidx.annotation.NonNull;
9+
import java.security.PrivateKey;
10+
import java.security.cert.X509Certificate;
11+
import java.util.List;
12+
13+
/**
14+
* ProxyApi implementation for {@link ClientCertRequest}. This class may handle instantiating native
15+
* object instances that are attached to a Dart instance or handle method calls on the associated
16+
* native class or an instance of that class.
17+
*/
18+
class ClientCertRequestProxyApi extends PigeonApiClientCertRequest {
19+
ClientCertRequestProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
20+
super(pigeonRegistrar);
21+
}
22+
23+
@Override
24+
public void cancel(@NonNull ClientCertRequest pigeon_instance) {
25+
pigeon_instance.cancel();
26+
}
27+
28+
@Override
29+
public void ignore(@NonNull ClientCertRequest pigeon_instance) {
30+
pigeon_instance.ignore();
31+
}
32+
33+
@Override
34+
public void proceed(
35+
@NonNull ClientCertRequest pigeon_instance,
36+
@NonNull PrivateKey privateKey,
37+
@NonNull List<? extends X509Certificate> chain) {
38+
pigeon_instance.proceed(privateKey, chain.toArray(new X509Certificate[0]));
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.os.Message;
8+
import androidx.annotation.NonNull;
9+
10+
/**
11+
* Proxy API implementation for `Message`.
12+
*
13+
* <p>This class may handle instantiating and adding native object instances that are attached to a
14+
* Dart instance or handle method calls on the associated native class or an instance of the class.
15+
*/
16+
public class MessageProxyApi extends PigeonApiAndroidMessage {
17+
public MessageProxyApi(@NonNull AndroidWebkitLibraryPigeonProxyApiRegistrar pigeonRegistrar) {
18+
super(pigeonRegistrar);
19+
}
20+
21+
@Override
22+
public void sendToTarget(@NonNull Message pigeon_instance) {
23+
pigeon_instance.sendToTarget();
24+
}
25+
}

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/ProxyApiRegistrar.java

+49
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ void logError(String tag, Throwable exception) {
5656
+ Log.getStackTraceString(exception));
5757
}
5858

59+
/** Creates an exception when the `unknown` enum value is passed to a host method. */
60+
@NonNull
61+
IllegalArgumentException createUnknownEnumException(@NonNull Object enumValue) {
62+
return new IllegalArgumentException(enumValue + " doesn't represent a native value.");
63+
}
64+
65+
/** Creates the error message when a method is called on an unsupported version. */
66+
@NonNull
67+
String createUnsupportedVersionMessage(
68+
@NonNull String method, @NonNull String versionRequirements) {
69+
return method + " requires " + versionRequirements + ".";
70+
}
71+
5972
@NonNull
6073
@Override
6174
public PigeonApiWebResourceRequest getPigeonApiWebResourceRequest() {
@@ -183,6 +196,42 @@ public PigeonApiHttpAuthHandler getPigeonApiHttpAuthHandler() {
183196
return new HttpAuthHandlerProxyApi(this);
184197
}
185198

199+
@NonNull
200+
@Override
201+
public PigeonApiClientCertRequest getPigeonApiClientCertRequest() {
202+
return new ClientCertRequestProxyApi(this);
203+
}
204+
205+
@NonNull
206+
@Override
207+
public PigeonApiSslErrorHandler getPigeonApiSslErrorHandler() {
208+
return new SslErrorHandlerProxyApi(this);
209+
}
210+
211+
@NonNull
212+
@Override
213+
public PigeonApiSslError getPigeonApiSslError() {
214+
return new SslErrorProxyApi(this);
215+
}
216+
217+
@NonNull
218+
@Override
219+
public PigeonApiSslCertificateDName getPigeonApiSslCertificateDName() {
220+
return new SslCertificateDNameProxyApi(this);
221+
}
222+
223+
@NonNull
224+
@Override
225+
public PigeonApiSslCertificate getPigeonApiSslCertificate() {
226+
return new SslCertificateProxyApi(this);
227+
}
228+
229+
@NonNull
230+
@Override
231+
public PigeonApiAndroidMessage getPigeonApiAndroidMessage() {
232+
return new MessageProxyApi(this);
233+
}
234+
186235
@NonNull
187236
public Context getContext() {
188237
return context;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.net.http.SslCertificate;
8+
import androidx.annotation.NonNull;
9+
10+
/**
11+
* ProxyApi implementation for {@link SslCertificate.DName}. This class may handle instantiating
12+
* native object instances that are attached to a Dart instance or handle method calls on the
13+
* associated native class or an instance of that class.
14+
*/
15+
class SslCertificateDNameProxyApi extends PigeonApiSslCertificateDName {
16+
SslCertificateDNameProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
17+
super(pigeonRegistrar);
18+
}
19+
20+
@NonNull
21+
@Override
22+
public String getCName(@NonNull SslCertificate.DName pigeon_instance) {
23+
return pigeon_instance.getCName();
24+
}
25+
26+
@NonNull
27+
@Override
28+
public String getDName(@NonNull SslCertificate.DName pigeon_instance) {
29+
return pigeon_instance.getDName();
30+
}
31+
32+
@NonNull
33+
@Override
34+
public String getOName(@NonNull SslCertificate.DName pigeon_instance) {
35+
return pigeon_instance.getOName();
36+
}
37+
38+
@NonNull
39+
@Override
40+
public String getUName(@NonNull SslCertificate.DName pigeon_instance) {
41+
return pigeon_instance.getUName();
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.net.http.SslCertificate;
8+
import android.os.Build;
9+
import android.util.Log;
10+
import androidx.annotation.NonNull;
11+
import androidx.annotation.Nullable;
12+
import java.util.Date;
13+
14+
/**
15+
* ProxyApi implementation for {@link SslCertificate}. This class may handle instantiating native
16+
* object instances that are attached to a Dart instance or handle method calls on the associated
17+
* native class or an instance of that class.
18+
*/
19+
class SslCertificateProxyApi extends PigeonApiSslCertificate {
20+
SslCertificateProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
21+
super(pigeonRegistrar);
22+
}
23+
24+
@NonNull
25+
@Override
26+
public ProxyApiRegistrar getPigeonRegistrar() {
27+
return (ProxyApiRegistrar) super.getPigeonRegistrar();
28+
}
29+
30+
@Nullable
31+
@Override
32+
public android.net.http.SslCertificate.DName getIssuedBy(
33+
@NonNull SslCertificate pigeon_instance) {
34+
return pigeon_instance.getIssuedBy();
35+
}
36+
37+
@Nullable
38+
@Override
39+
public android.net.http.SslCertificate.DName getIssuedTo(
40+
@NonNull SslCertificate pigeon_instance) {
41+
return pigeon_instance.getIssuedTo();
42+
}
43+
44+
@Nullable
45+
@Override
46+
public Long getValidNotAfterMsSinceEpoch(@NonNull SslCertificate pigeon_instance) {
47+
final Date date = pigeon_instance.getValidNotAfterDate();
48+
if (date != null) {
49+
return date.getTime();
50+
}
51+
return null;
52+
}
53+
54+
@Nullable
55+
@Override
56+
public Long getValidNotBeforeMsSinceEpoch(@NonNull SslCertificate pigeon_instance) {
57+
final Date date = pigeon_instance.getValidNotBeforeDate();
58+
if (date != null) {
59+
return date.getTime();
60+
}
61+
return null;
62+
}
63+
64+
@Nullable
65+
@Override
66+
public java.security.cert.X509Certificate getX509Certificate(
67+
@NonNull SslCertificate pigeon_instance) {
68+
if (getPigeonRegistrar().sdkIsAtLeast(Build.VERSION_CODES.Q)) {
69+
return pigeon_instance.getX509Certificate();
70+
} else {
71+
Log.d(
72+
"SslCertificateProxyApi",
73+
getPigeonRegistrar()
74+
.createUnsupportedVersionMessage(
75+
"SslCertificate.getX509Certificate", "Build.VERSION_CODES.Q"));
76+
return null;
77+
}
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.webkit.SslErrorHandler;
8+
import androidx.annotation.NonNull;
9+
10+
/**
11+
* ProxyApi implementation for {@link SslErrorHandler}. This class may handle instantiating native
12+
* object instances that are attached to a Dart instance or handle method calls on the associated
13+
* native class or an instance of that class.
14+
*/
15+
class SslErrorHandlerProxyApi extends PigeonApiSslErrorHandler {
16+
SslErrorHandlerProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
17+
super(pigeonRegistrar);
18+
}
19+
20+
@Override
21+
public void cancel(@NonNull SslErrorHandler pigeon_instance) {
22+
pigeon_instance.cancel();
23+
}
24+
25+
@Override
26+
public void proceed(@NonNull SslErrorHandler pigeon_instance) {
27+
pigeon_instance.proceed();
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.webviewflutter;
6+
7+
import android.net.http.SslError;
8+
import androidx.annotation.NonNull;
9+
10+
/**
11+
* ProxyApi implementation for {@link SslError}. This class may handle instantiating native object
12+
* instances that are attached to a Dart instance or handle method calls on the associated native
13+
* class or an instance of that class.
14+
*/
15+
class SslErrorProxyApi extends PigeonApiSslError {
16+
SslErrorProxyApi(@NonNull ProxyApiRegistrar pigeonRegistrar) {
17+
super(pigeonRegistrar);
18+
}
19+
20+
@NonNull
21+
@Override
22+
public ProxyApiRegistrar getPigeonRegistrar() {
23+
return (ProxyApiRegistrar) super.getPigeonRegistrar();
24+
}
25+
26+
@NonNull
27+
@Override
28+
public android.net.http.SslCertificate certificate(@NonNull SslError pigeon_instance) {
29+
return pigeon_instance.getCertificate();
30+
}
31+
32+
@NonNull
33+
@Override
34+
public String url(@NonNull SslError pigeon_instance) {
35+
return pigeon_instance.getUrl();
36+
}
37+
38+
@NonNull
39+
@Override
40+
public SslErrorType getPrimaryError(@NonNull SslError pigeon_instance) {
41+
switch (pigeon_instance.getPrimaryError()) {
42+
case SslError.SSL_DATE_INVALID:
43+
return SslErrorType.DATE_INVALID;
44+
case SslError.SSL_EXPIRED:
45+
return SslErrorType.EXPIRED;
46+
case SslError.SSL_IDMISMATCH:
47+
return SslErrorType.ID_MISMATCH;
48+
case SslError.SSL_INVALID:
49+
return SslErrorType.INVALID;
50+
case SslError.SSL_NOTYETVALID:
51+
return SslErrorType.NOT_YET_VALID;
52+
case SslError.SSL_UNTRUSTED:
53+
return SslErrorType.UNTRUSTED;
54+
default:
55+
return SslErrorType.UNKNOWN;
56+
}
57+
}
58+
59+
@Override
60+
public boolean hasError(@NonNull SslError pigeon_instance, @NonNull SslErrorType error) {
61+
int nativeError = -1;
62+
switch (error) {
63+
case DATE_INVALID:
64+
nativeError = SslError.SSL_DATE_INVALID;
65+
break;
66+
case EXPIRED:
67+
nativeError = SslError.SSL_EXPIRED;
68+
break;
69+
case ID_MISMATCH:
70+
nativeError = SslError.SSL_IDMISMATCH;
71+
break;
72+
case INVALID:
73+
nativeError = SslError.SSL_INVALID;
74+
break;
75+
case NOT_YET_VALID:
76+
nativeError = SslError.SSL_NOTYETVALID;
77+
break;
78+
case UNTRUSTED:
79+
nativeError = SslError.SSL_UNTRUSTED;
80+
break;
81+
case UNKNOWN:
82+
throw getPigeonRegistrar().createUnknownEnumException(error);
83+
}
84+
return pigeon_instance.hasError(nativeError);
85+
}
86+
}

0 commit comments

Comments
 (0)