blob: 55d3d7d385e7688621b152bcfb3e39c6240796c1 [file] [log] [blame] [view]
Peter E Connfc686482025-03-21 15:42:511# How WebView Full Screen Works
2
3[TOC]
4
5Note: In this doc, `WebView` in code font means the `WebView` class that's a
6subclass of `View`, whereas WebView in normal font means the WebView product in
7general.
8
9## How apps use full screen
10
11You can see an example of how to support WebView full screen in your application
12in [the WebView
13shell](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserFragment.java;l=500;drc=cfb4fb0b1658a915db8c470751f511bb8360a9bc).
14The app overrides `WebChromeClient#onShowCustomView` to do something like:
15
16```java
17@Override
18public void onShowCustomView(
19 View view, WebChromeClient.CustomViewCallback callback) {
20 if (mFullscreenView != null) {
21 ((ViewGroup) mFullscreenView.getParent()).removeView(mFullscreenView);
22 }
23 mFullscreenView = view;
24 requireActivity()
25 .getWindow()
26 .addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
27 requireActivity()
28 .getWindow()
29 .addContentView(
30 mFullscreenView,
31 new FrameLayout.LayoutParams(
32 ViewGroup.LayoutParams.MATCH_PARENT,
33 ViewGroup.LayoutParams.MATCH_PARENT,
34 Gravity.CENTER));
35}
36```
37
38Essentially, when the web contents requests to go full screen, WebView creates a
39`View` (a
40[FullScreenView](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/FullScreenView.java))
41and hands it to the app to attach to the window. Usually the existing `WebView`
42remains attached to the window, but obscured by the full screen `View`.
43
44When the user exits full screen through the web contents, or through invoking
45the callback, `onHideCustomView` is called, where the app should remove
46`mFullscreenView` from the window.
47
48```java
49@Override
50public void onHideCustomView() {
51 if (mFullscreenView == null) {
52 return;
53 }
54 requireActivity()
55 .getWindow()
56 .clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
57 ((ViewGroup) mFullscreenView.getParent()).removeView(mFullscreenView);
58 mFullscreenView = null;
59}
60```
61
62Of all the apps that override `WebChromeClient`, ~85% of them override
63`onShowCustomView`. If an app does not, WebView reports to the web page that
64fullscreen mode is not supported.
65
66## How this works
67
68Broadly speaking, the API on the `WebView` class can be split into two parts -
69stuff to do with the web content (eg, `loadUrl`, `goBack`) and stuff to do with
70integrating into the View hierarchy (eg, `onDraw`, `requestFocus`). Inside
71`AwContents`, the View responsibilities are collected in the `AwViewMethods`
72interface, so we end up with the following:
73
74![WebView attached to AwViewMethods](images/webview_not_full_screen.png)
75
76When full screen is triggered, the web page starts being drawn through
77[FullScreenView](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/FullScreenView.java)
78instead, so all the integration with the View hierarchy must come from there
79instead. At the same time, we don’t want `AwViewMethods` being triggered by both
80the `FullScreenView` and the `WebView`, so we attach the `WebView` to a
81[NullAwViewMethods](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java),
82where everything is effectively a no-op.
83
84![WebView attached to NullAwViewMethods](images/webview_full_screen.png)
85
86This means that a call to `WebView#loadUrl` will trigger a page load, but it
87will still be drawn through the `FullScreenView`.
88
89## What you need to know
90
91The main thing you need to keep in mind is that `AwContents` can be moved
92between Views (between `WebView` and `FullScreenView`).
93
94Currently, the code is a little confused, with
95[AwContents#onAttachedToWindow](https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/AwContents.java;l=3366;drc=71a590f3fd3c3c34f1fd48bbaf9e5357f2df4832)
96tying features (such as the window coverage tracker, the display cutout
97controller, the frame metrics listener) to the `WebView` that should be moved
98over to the `FullScreenView` when it’s used, but aren’t. These should get fixed
99soon.