Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Handle not sending the request to the client in the controller
  • Loading branch information
petermnt committed Mar 27, 2024
commit d1d3bd6163977bd15417918b942fc18c221aa229
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,11 @@ public void onReceivedError(
@Override
public boolean shouldOverrideUrlLoading(
@NonNull WebView view, @NonNull WebResourceRequest request) {
if (!request.isForMainFrame()) {
// The client is only allowed to stop navigations that target the main frame because
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
return false;
}

flutterApi.requestLoading(this, view, request, reply -> {});
return returnValueForShouldOverrideUrlLoading;

// The client is only allowed to stop navigations that target the main frame because
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
}

// Legacy codepath for < 24; newer versions use the variant above.
Expand Down Expand Up @@ -192,14 +189,11 @@ public void onReceivedError(
@Override
public boolean shouldOverrideUrlLoading(
@NonNull WebView view, @NonNull WebResourceRequest request) {
if (!request.isForMainFrame()) {
// The client is only allowed to stop navigations that target the main frame because
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
return false;
}

flutterApi.requestLoading(this, view, request, reply -> {});
return returnValueForShouldOverrideUrlLoading;

// The client is only allowed to stop navigations that target the main frame because
// overridden URLs are passed to `loadUrl` and `loadUrl` cannot load a subframe.
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
}

// Legacy codepath for < Lollipop; newer versions use the variant above.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

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

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verifyNoInteractions(mockFlutterApi);
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

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

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verifyNoInteractions(mockFlutterApi);
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

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

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verifyNoInteractions(mockFlutterApi);
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

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

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verifyNoInteractions(mockFlutterApi);
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,11 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
final LoadRequestCallback? onLoadRequest = _onLoadRequest;
final NavigationRequestCallback? onNavigationRequest = _onNavigationRequest;

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,66 @@ void main() {
expect(callbackNavigationRequest, isNull);
});

test(
'onNavigationRequest from requestLoading should be called when request is for main frame',
() {
final AndroidNavigationDelegate androidNavigationDelegate =
AndroidNavigationDelegate(_buildCreationParams());

NavigationRequest? callbackNavigationRequest;
androidNavigationDelegate
.setOnNavigationRequest((NavigationRequest navigationRequest) {
callbackNavigationRequest = navigationRequest;
return NavigationDecision.prevent;
});

androidNavigationDelegate.setOnLoadRequest((_) async {});

CapturingWebViewClient.lastCreatedDelegate.requestLoading!(
android_webview.WebView.detached(),
android_webview.WebResourceRequest(
url: 'https://www.google.com',
isForMainFrame: true,
isRedirect: true,
hasGesture: true,
method: 'GET',
requestHeaders: <String, String>{'X-Mock': 'mocking'},
),
);

expect(callbackNavigationRequest, isNotNull);
});

test(
'onNavigationRequest from requestLoading should not be called when request is not for main frame',
() {
final AndroidNavigationDelegate androidNavigationDelegate =
AndroidNavigationDelegate(_buildCreationParams());

NavigationRequest? callbackNavigationRequest;
androidNavigationDelegate
.setOnNavigationRequest((NavigationRequest navigationRequest) {
callbackNavigationRequest = navigationRequest;
return NavigationDecision.prevent;
});

androidNavigationDelegate.setOnLoadRequest((_) async {});

CapturingWebViewClient.lastCreatedDelegate.requestLoading!(
android_webview.WebView.detached(),
android_webview.WebResourceRequest(
url: 'https://www.google.com',
isForMainFrame: false,
isRedirect: true,
hasGesture: true,
method: 'GET',
requestHeaders: <String, String>{'X-Mock': 'mocking'},
),
);

expect(callbackNavigationRequest, isNull);
});

test(
'onLoadRequest from requestLoading should not be called when navigationRequestCallback is not specified',
() {
Expand Down Expand Up @@ -598,6 +658,7 @@ class CapturingWebChromeClient extends android_webview.WebChromeClient {
}) : super.detached() {
lastCreatedDelegate = this;
}

static CapturingWebChromeClient lastCreatedDelegate =
CapturingWebChromeClient();
}
Expand All @@ -611,6 +672,7 @@ class CapturingDownloadListener extends android_webview.DownloadListener {
}) : super.detached() {
lastCreatedListener = this;
}

static CapturingDownloadListener lastCreatedListener =
CapturingDownloadListener(onDownloadStart: (_, __, ___, ____, _____) {});
}