blob: 749652ccf89cc09a3ed5edc4349b7db957632c02 [file] [view]
# //android\_webview/renderer/
This folder holds WebView's renderer-specific code.
## Folder dependencies
Like with other content embedders, `//android_webview/renderer/` can depend on
`//android_webview/common/` but not `//android_webview/browser/`. It can also
depend on content layer (and lower layers) as other embedders would (ex. can
depend on `//content/public/renderer/`, `//content/public/common/`).
## In-process renderer
WebView used to run in "single process" mode, which is when the renderer code
runs inside the browser process on a separate thread called the renderer thread.
Because this runs inside the browser process, there is no sandboxing (a
compromised renderer
has permission to access the disk or do anything else which the
browser process is capable of).
*** note
**Note:** this is largely obsolete and irrelevant. The in-process renderer was
the default on Lollipop (API 21) through Nougat MR1/MR2 (API 25), however modern
WebView releases have [dropped support for these versions][1].
Devices running Oreo (Api 26) through Q (API 29) will generally use an
out-of-process renderer (see next section), however it's possible these will use
in-process renderer on low-memory devices. However memory optimizations in
Android R (API 30) mean that WebView **always** uses out-of-process renderer on
Android R and above.
As of M139, the [only supported configuration][2] using single process mode is
Android Q low-memory devices.
***
## Out-of-process renderer
Starting in Oreo (API 26) WebView has a single out-of-process renderer (we
sometimes refer to this as "multiprocess mode"). This is enabled for all 64-bit
devices, for 32-bit devices with high memory, and for all devices starting in
Android 11 (API 30). Low memory 32-bit devices running API26-29 still use an
in-process renderer as before.
Note that in this mode, the renderer process and the host app ("browser process")
may have different bitness. See [architecture.md](../docs/architecture.md).
The out-of-process renderer is enabled by new Android APIs
(`android:externalService` and [Content.bindIsolatedService][3]), to create sandboxed processes which run in the
_embedding app's context_ rather than the WebView provider's context. These
processes will be named something like
`com.google.android.webview:sandboxed_process0` and it will run an
Android service named `org.chromium.content.app.SandboxedProcessService0`. The
package name will match the current WebView provider and the number suffix will
usually be a `0` or a `1`.
Without this API, we could only declare a **fixed** number of renderer processes
to run in the WebView provider's context, and WebView (running in the app's
process) would have to pick one of these declared services to use as the
renderer process. This would be a security problem because:
* There's no trivial way for WebView (running in the app) to figure out which
services are in-use, and reusing a service which is already in-use would mix
content from two different apps in the same process (which violates Android's
trust model).
* Even if we had a way to pick a not-in-use service, because WebView runs in the
app's process, a malicious app could override this logic to intentionally pick
an in-use service, with the goal of compromising another app on the system.
* We have to declare a fixed number of services in the manifest. Even if we
could securely put each app's content in a separate renderer process,
supposing we've declared N services, the N+1th app will not have an empty
service available and will have to share.
Running renderers in the app's context ensures content from two apps are always
isolated, aligning with the Android security model.
### Recovering from renderer crashes
Starting with Oreo, Android apps have the opportunity to recover from renderer
crashes by overriding [`WebViewClient#onRenderProcessGone()`][4]. However, for
backwards compatibility, WebView crashes the browser process if the app has not
overridden this callback. Therefore, unlike in Chrome, renderer crashes are
often non-recoverable.
## Writing automated tests for either single process or multiprocess mode
You can annotate WebView javatests with `@OnlyRunIn`. See [test instructions][5]
for details about how to use this annotation.
The default behavior (if no annotation is specified) is that the test will run
in both modes.
## Multiple renderers
Apps can create multiple WebView Profiles, in which case each Profile gets its
own renderer process. Please see [WebViewCompat.setProfile][6] if you would like
to use multiple Profiles for different WebView instances.
WebView does not generally support multiple renderer processes in a single
profile, however this may be supported in the future. The only exception today
is that WebView can create a separate renderer process for showing builtin error
pages (known as `webui` in Chromium architecture), such as Safe Browsing
interstitial warnings.
## See also
Learn about [Chrome Android Sandbox Design][7] to understand how WebView's
renderer process is sandboxed to mitigate the security impact of a compromised
renderer.
[1]: https://groups.google.com/a/chromium.org/g/chromium-dev/c/B9AYI3WAvRo/m/tpWwhw4KBQAJ
[2]: https://groups.google.com/a/chromium.org/g/chromium-dev/c/vEZz0721rUY/m/pUIgqXxNBQAJ
[3]: https://developer.android.com/reference/android/content/Context#bindIsolatedService(android.content.Intent,%20int,%20java.lang.String,%20java.util.concurrent.Executor,%20android.content.ServiceConnection)
[4]: https://developer.android.com/reference/android/webkit/WebViewClient.html#onRenderProcessGone(android.webkit.WebView,%20android.webkit.RenderProcessGoneDetail)
[5]: /android_webview/docs/test-instructions.md#instrumentation-test-process-modes
[6]: https://developer.android.com/reference/androidx/webkit/WebViewCompat#setProfile(android.webkit.WebView,java.lang.String)
[7]: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/android-sandbox.md