Skip to content

Commit d1d3bd6

Browse files
committed
Handle not sending the request to the client in the controller
1 parent 361c19d commit d1d3bd6

File tree

5 files changed

+83
-21
lines changed

5 files changed

+83
-21
lines changed

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

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,11 @@ public void onReceivedError(
8787
@Override
8888
public boolean shouldOverrideUrlLoading(
8989
@NonNull WebView view, @NonNull WebResourceRequest request) {
90-
if (!request.isForMainFrame()) {
91-
// The client is only allowed to stop navigations that target the main frame because
92-
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
93-
return false;
94-
}
95-
9690
flutterApi.requestLoading(this, view, request, reply -> {});
97-
return returnValueForShouldOverrideUrlLoading;
91+
92+
// The client is only allowed to stop navigations that target the main frame because
93+
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
94+
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
9895
}
9996

10097
// Legacy codepath for < 24; newer versions use the variant above.
@@ -192,14 +189,11 @@ public void onReceivedError(
192189
@Override
193190
public boolean shouldOverrideUrlLoading(
194191
@NonNull WebView view, @NonNull WebResourceRequest request) {
195-
if (!request.isForMainFrame()) {
196-
// The client is only allowed to stop navigations that target the main frame because
197-
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
198-
return false;
199-
}
200-
201192
flutterApi.requestLoading(this, view, request, reply -> {});
202-
return returnValueForShouldOverrideUrlLoading;
193+
194+
// The client is only allowed to stop navigations that target the main frame because
195+
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
196+
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
203197
}
204198

205199
// Legacy codepath for < Lollipop; newer versions use the variant above.

packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientCompatImplTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import static org.mockito.ArgumentMatchers.eq;
1212
import static org.mockito.Mockito.mock;
1313
import static org.mockito.Mockito.verify;
14-
import static org.mockito.Mockito.verifyNoInteractions;
1514
import static org.mockito.Mockito.when;
1615

1716
import android.net.Uri;
@@ -128,7 +127,8 @@ public void urlLoadingNotForMainFrame() {
128127
when(mockRequest.isForMainFrame()).thenReturn(false);
129128

130129
assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
131-
verifyNoInteractions(mockFlutterApi);
130+
verify(mockFlutterApi)
131+
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
132132
}
133133

134134
@Test
@@ -139,7 +139,8 @@ public void urlLoadingNotForMainFrameWithOverride() {
139139
when(mockRequest.isForMainFrame()).thenReturn(false);
140140

141141
assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
142-
verifyNoInteractions(mockFlutterApi);
142+
verify(mockFlutterApi)
143+
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
143144
}
144145

145146
@Test

packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientImplTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import static org.mockito.ArgumentMatchers.eq;
1212
import static org.mockito.Mockito.mock;
1313
import static org.mockito.Mockito.verify;
14-
import static org.mockito.Mockito.verifyNoInteractions;
1514
import static org.mockito.Mockito.when;
1615

1716
import android.net.Uri;
@@ -125,7 +124,8 @@ public void urlLoadingNotForMainFrame() {
125124
when(mockRequest.isForMainFrame()).thenReturn(false);
126125

127126
assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
128-
verifyNoInteractions(mockFlutterApi);
127+
verify(mockFlutterApi)
128+
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
129129
}
130130

131131
@Test
@@ -136,7 +136,8 @@ public void urlLoadingNotForMainFrameWithOverride() {
136136
when(mockRequest.isForMainFrame()).thenReturn(false);
137137

138138
assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
139-
verifyNoInteractions(mockFlutterApi);
139+
verify(mockFlutterApi)
140+
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
140141
}
141142

142143
@Test

packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,11 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
14641464
final LoadRequestCallback? onLoadRequest = _onLoadRequest;
14651465
final NavigationRequestCallback? onNavigationRequest = _onNavigationRequest;
14661466

1467-
if (onNavigationRequest == null || onLoadRequest == null) {
1467+
// The client is only allowed to stop navigations that target the main frame because
1468+
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
1469+
if (!isForMainFrame ||
1470+
onNavigationRequest == null ||
1471+
onLoadRequest == null) {
14681472
return;
14691473
}
14701474

packages/webview_flutter/webview_flutter_android/test/android_navigation_delegate_test.dart

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,66 @@ void main() {
163163
expect(callbackNavigationRequest, isNull);
164164
});
165165

166+
test(
167+
'onNavigationRequest from requestLoading should be called when request is for main frame',
168+
() {
169+
final AndroidNavigationDelegate androidNavigationDelegate =
170+
AndroidNavigationDelegate(_buildCreationParams());
171+
172+
NavigationRequest? callbackNavigationRequest;
173+
androidNavigationDelegate
174+
.setOnNavigationRequest((NavigationRequest navigationRequest) {
175+
callbackNavigationRequest = navigationRequest;
176+
return NavigationDecision.prevent;
177+
});
178+
179+
androidNavigationDelegate.setOnLoadRequest((_) async {});
180+
181+
CapturingWebViewClient.lastCreatedDelegate.requestLoading!(
182+
android_webview.WebView.detached(),
183+
android_webview.WebResourceRequest(
184+
url: 'https://www.google.com',
185+
isForMainFrame: true,
186+
isRedirect: true,
187+
hasGesture: true,
188+
method: 'GET',
189+
requestHeaders: <String, String>{'X-Mock': 'mocking'},
190+
),
191+
);
192+
193+
expect(callbackNavigationRequest, isNotNull);
194+
});
195+
196+
test(
197+
'onNavigationRequest from requestLoading should not be called when request is not for main frame',
198+
() {
199+
final AndroidNavigationDelegate androidNavigationDelegate =
200+
AndroidNavigationDelegate(_buildCreationParams());
201+
202+
NavigationRequest? callbackNavigationRequest;
203+
androidNavigationDelegate
204+
.setOnNavigationRequest((NavigationRequest navigationRequest) {
205+
callbackNavigationRequest = navigationRequest;
206+
return NavigationDecision.prevent;
207+
});
208+
209+
androidNavigationDelegate.setOnLoadRequest((_) async {});
210+
211+
CapturingWebViewClient.lastCreatedDelegate.requestLoading!(
212+
android_webview.WebView.detached(),
213+
android_webview.WebResourceRequest(
214+
url: 'https://www.google.com',
215+
isForMainFrame: false,
216+
isRedirect: true,
217+
hasGesture: true,
218+
method: 'GET',
219+
requestHeaders: <String, String>{'X-Mock': 'mocking'},
220+
),
221+
);
222+
223+
expect(callbackNavigationRequest, isNull);
224+
});
225+
166226
test(
167227
'onLoadRequest from requestLoading should not be called when navigationRequestCallback is not specified',
168228
() {
@@ -598,6 +658,7 @@ class CapturingWebChromeClient extends android_webview.WebChromeClient {
598658
}) : super.detached() {
599659
lastCreatedDelegate = this;
600660
}
661+
601662
static CapturingWebChromeClient lastCreatedDelegate =
602663
CapturingWebChromeClient();
603664
}
@@ -611,6 +672,7 @@ class CapturingDownloadListener extends android_webview.DownloadListener {
611672
}) : super.detached() {
612673
lastCreatedListener = this;
613674
}
675+
614676
static CapturingDownloadListener lastCreatedListener =
615677
CapturingDownloadListener(onDownloadStart: (_, __, ___, ____, _____) {});
616678
}

0 commit comments

Comments
 (0)