blob: b71ab638157f48e62294ba8d2135684adac92258 [file] [log] [blame] [view]
Shimi Zhangaa4a1a4eb2020-03-21 01:20:141# How does [`WebChromeClient#onCreateWindow`](https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)) work?
2
3[TOC]
4
5## Summary
6
7This is a technical explanation of how `onCreateWindow` and the related API are
8implemented from content layer APIs.
9
10## Example usage
11
12Let's look at example code snippets first to see how an app could use these API:
13
14On the app side (in Java):
15
16```java
17// Configure parent WebView.
18WebView webView = ...;
19webView.getSettings().setJavaScriptEnabled(true);
20webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
21webView.getSettings().setSupportMultipleWindows(true);
22
23webView.setWebChromeClient(new WebChromeClient() {
24 @Override
25 public boolean onCreateWindow(
26 WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
27 // Create child WebView. It is better to not reuse an existing WebView.
28 WebView childWebView = ...;
29
30 WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
31 transport.setWebView(childWebView);
32 resultMsg.sentToTarget();
33 return true;
34 }
35});
36
37webView.loadUrl(...);
38```
39
40On the web page side (in JavaScript):
41
42```javascript
43window.open("www.example.com");
44```
45
46## What happened under the hood
47
481. When the parent WebView loads the web page and runs the JavaScript snippet,
Nate Fischer8924a23f2021-05-04 00:05:2549 [`AwWebContentsDelegate::AddNewContents`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/browser/aw_web_contents_delegate.h;l=43;drc=3abb32da2944ffe178dd66f404e7e1bb88a58ed0)
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1450 will be called. The corresponding Java side
Nate Fischer8924a23f2021-05-04 00:05:2551 [`AwWebContentsDelegate#addNewContents`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegate.java;l=30;drc=a19051603849d7810b3569daf158aceb23aad1da)
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1452 is called from the native.
53
541. At the same time,
Nate Fischer8924a23f2021-05-04 00:05:2555 [`AwContents::SetPendingWebContentsForPopup`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/browser/aw_contents.cc;l=1099;drc=7776bbb38c4e394b5be085bc8c5bc02df5fa22dc)
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1456 creates native popup AwContents with the given `WebContents` and stores it as
57 `pending_contents_` in the parent `AwContents` object without Java
58 counterpart created. Note that since `pending_contents_` can only store one
59 popup AwContents, WebView doesn't support multiple pending popups.
60
611. `WebChromeClient#onCreateWindow` is called from step 1, with the code snippet
62 above, `childWebView` is set to the `WebViewTransport` and
63 `resultMsg.sendToTarget()` will send the `childWebView` to its receiver.
64
651. `WebViewContentsClientAdapter` has a handler that receives the message sent
66 from `resultMsg.sendToTarget()`. It will trigger
Nate Fischer8924a23f2021-05-04 00:05:2567 [`WebViewChromium#completeWindowCreation`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java;l=265;drc=da3bb54157d4603b9c820d6cfdf61859f804dfb2),
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1468 then
Nate Fischer8924a23f2021-05-04 00:05:2569 [`AwContents#supplyContentsForPopup`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/AwContents.java;l=1455;drc=4afe92995db1279895f8a40b69c374bc298d750f)
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1470 is called on the parent WebView/AwContents.
71
721. `AwContents#supplyContentsForPopup` calls
Nate Fischer8924a23f2021-05-04 00:05:2573 [`AwContents#receivePopupContents`](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/AwContents.java;l=1475;drc=4afe92995db1279895f8a40b69c374bc298d750f)
Shimi Zhangaa4a1a4eb2020-03-21 01:20:1474 on the child WebView/AwContents. Child AwContents deletes the existing native
75 AwContents from the child WebView/AwContents, and pairs it with the
76 `pending_contents_` from the parent WebView/AwContents. In order to preserve
77 the status of the child WebView, all the flags and configurations need to be
78 re-applied to the `pending_contents_`. Loading on the native AwContents is
79 also resumed.