WebView
This directory contains key classes that are part of the WebView feature implementation, integrating //components/guest_view with the //extensions system.
Example - WebView permission request API behavior
The current Webview permission request API supports a small set of WebView permissions. Some of these permissions overlap with Web Permissions (e.g. media, geolocation, HID, pointer lock). Some of these are WebView-specific permissions (new window, javascript dialog, etc). In the browser process when a RenderFrameHost (RFH) is created, the RFH is configured to support WebView's handling for particular permission events (for plugins).
- ChromeContentBrowserClient::RegisterAssociatedInterfaceBindersForRenderFrameHost() adds a handler, BindPluginAuthHost, which binds receivers for the PluginAuthHost interface. For auth messages from a RFH in a webview, the receiver is bound to the webview's ChromeWebViewPermissionHelperDelegate. See Mojo & Services for details on message passing.
- Now when an auth message is received, the message will be handled by ChromeWebViewPermissionHelperDelegate.
When a WebView is created by the embedder, as part of WebView initialization in the browser process the WebView system will create a handler for permission events:
- WebViewGuest::DidInitialize() - creates a WebViewPermissionHelper and stores it on web_view_permission_helper_
- In extensions (non-Chrome), when WebViewPermissionHelper starts it uses the ExtensionsAPIClient to create a WebViewPermissionHelperDelegate. We'll focus just on the //chrome layer case:
- ChromeExtensionsAPIClient::CreateWebViewPermissionHelperDelegate() -- returns a ChromeWebViewPermissionHelperDelegate
The WebView embedder adds an event handler for permissionrequest events:
- Ex: pointerlock test:
- webview.addEventListener(‘permissionrequest’, function(e) { ... });
When the WebView embedded content requests a permission:
- Permissions::request()
- (through multiple layers of mojom and then to the PermissionManager...)
- PermissionManager::RequestPermissionsInternal()
- PermissionContextBase::RequestPermission()
At this point, some additional handling will occur that‘s permission-specific. We’ll skip over some of those steps but for one case -- geolocation -- we'll provide some of that detail:
- GeolocationPermissionContext::DecidePermission()
- GeolocationPermissionContextDelegate::DecidePermission()
- GeolocationPermissionContextExtensions::DecidePermission()
For geolocation, the last DecidePermission() call is where the WebView code intercepts the permission request. Stepping back to look at all of the permission types, the browser relays the permission into permission-specific code for each of those types similar to this. Here's a list of those intercepts, including geolocation:
- The permission request is intercepted. The interception point is permission-specific.
- pointerlock, media both use a WebContents pattern that allows a WebContentsDelegate to handle some auth requests. In these cases, WebViewGuest acts as the WebContentsDelegate.
- Pointerlock is intercepted in WebContentsImpl::RequestToLockPointer().
- Media is intercepted in WebContentsImpl::RequestMediaAccessPermission().
- Geolocation - GeolocationPermissionContextExtensions which inherits GeolocationPermissionContextDelegate. Intercepted in GeolocationPermissionContextExtensions::DecidePermission().
- Geolocation also has an override where it calls GuestViewBase::OverridePermissionResult() to ensure that for whatever origin, the permission look up result will always be ASK which leads into GeolocationPermissionContext::DecidePermission(). This is Controlled Frame-specific.
- HID checks whether a RenderFrameHost is in a WebView in ChromeHidDelegate
- New Window is called from WebViewGuest::CreateNewGuestWebViewWindow. Note this “newwindow” event is not from a permission request, but this is where we generate a permissionrequest event to capture it and send it to the embedder.
- File System is called from ChromeContentBrowserClient::AllowWorkerFileSystem and ContentSettingsManagerDelegate::AllowStorageAccess
- An extension function fires a
permissionrequest event.- The WebViewPermissionHelper::RequestPermission() call will dispatch a webview::kEventPermissionRequest event to the WebView host.
- The event is routed to the WebView host's script. If the event is handled and
request.allow() is called, the embedder indicates that the permission should be granted. But the grant is still subject to the embedder being trusted to grant the permission (see below).- Embedder's call to allow() invokes:
- PermissionRequest.prototype.allow()
- WebViewInternalSetPermissionFunction::Run()
- WebViewPermissionHelper::SetPermission()
- For media and geolocation, an additional permission call happens with the requester transformed from the embedded document to the embedder document, as if the embedder is requesting the permission itself (media, geolocation).
- SetPermission() finds the associated permission request, runs the associated callback (passing the permission request result to the callback), then cleans up the entry from the permission request list.
- The associated callback will have been set for each of the different types of permission requests. Here are the callbacks:
- Geolocation - ChromeWebViewPermissionHelperDelegate:: OnGeolocationPermissionResponse()
- media - WebViewPermissionHelper::OnMediaPermissionResponse()
- pointerlock - ChromeWebViewPermissionHelperDelegate:: OnPointerLockPermissionResponse()
- HID - ChromeWebViewPermissionHelperDelegate::OnHidPermissionResponse()
- Once the embedder allows a permission request, depending on the permission type, the embedder's permission is also checked.
All other PermissionTypes, except for geolocation, audio and video, are explicitly rejected as “not requestable” in WebView.