Chromium Android WebView是Chromium专为Android WebView提供一个对Content的封装层。从整体上来看可以理解为一个特殊化的Embedder, 功能可以概括为:
1. 对Content和部分Browser Components封装到Java实现,供AOSP WebView调用实现WebView功能。
2. 实现Android WebView使用的单进程渲染架构。
3. 配置网络模块,并实现特定需要的scheme解析。
Content作为一个能力提供者,所以它的API也被称为SPI, 即Service Provider Interface。CAW一方面要调用Content的接口执行操作,另一方面扩展Content需要Embedder实现的接口(Client类和Observer类)。
其架构如下:
其内部包括了6个部分:
native & java:封装CAW为java实现,供上层的AOSP WebView使用。
ContentMainDelegate (AwMainDelegate): 像其它Embedder一个,为配合Content的启动管理者ContentMainRunner提供启动功能。
Component Clients: 为使用到的Browser Components提供客户端代码。比如AutoFill的客户端AwAutofillClient, 还有一个是WebContentsDelegate。
Renderer: 则是负责利用Renderer进程的扩展机制(基本上都是Observers), 对Renderer进行干预。
Browser:负责实现Browser进程的业务逻辑,其中也包括了net和renderer_host两个子项目。
*CAW同时需要使用到网络模块。网络模块本身是一个公共的基础组件。
*以Renderer/Browser的目录命名来区分针对不同进程下功能的实现,这在其它模块里也是普遍使用的方式,如Components。
代码的命名空间都在android_webview下。
ContentMainDelegate
代码在src/android_webview/lib/main。
ContentMainDelegate是与Content交互的中心接口,负责具体的执行启动过程,以及按需要创建出与不同进程/线程交互的四个Clients,负责Content初化配置。
主要功能包括:
1. 对应上面类图中前三个函数。它可以干预启动过程,特别是在启动过程指定了一些功能的开关。比如禁用了File System API, WebRTC hardware decoding等。以下是启动的流程:
2. 对应上面类图中后四个函数。可以让Embedder自定义Content的行为。比如ContentRendererClient和ContentBrowserClient, 分别是针对Renderer和Browser进程的扩展机制。下面会再展开。
API (native & java)
目录: src/android_webview/java 和src/android_webview/native
AOSP WebView对外提供一个WebView控件,而CAW则负责提供AwContents封装WebView所需要的Contents功能。如下图所示:
另一个示例CookieManager,则是实现到net::CookieMonster的桥接:
主要的接口类包括负责加载native library等初始化操作的AwBrowserProcess, 以及围绕着AwContents的几个核心类, 既有直接注册于Content层的Observer实现的(AwContentsClient),也有通过native操作Content的(AwSettings):
其中AwContentsClient是一个组合的结果,来自于Content层的两个重要通知接口ConentViewClient,ContentVideoViewClient, WebContentsObserver都会转到AwContentsClient,再提供给AOSP层。
AwBrowserContext存储Browser所需要的一些对象,如SharedPreferences (Android的一个基于XML的存储机制), CookieManager等。
(SharedPreferences主要用于AwGeolocationPermissions存储在各个域名下的开关设置,是否可以集成到统一的Settings? 或者Global Settings参考SharedPreferences来实现?)
另外在WebView中定义的一些相关类,都可以在这层找到对应的实现。
android.webview.WebStorage <——> AwQuotaManagerBridge <—JNI—> storage::QuotaManager
android.webview.CookieManager <——> AwCookieManager <—JNI—>net::CookieMonster
Renderer
交互的手段主要基于Renderer的扩展,包括Observer, Client和IPC机制。
涉及的类图:
各类的职责可以从其方法定义上就可以看出来,不再赘述。
下图可以反应出其中RenderViewObserver的机制:
*其中AwRenderViewHostExt是类似的类,属于在Browser进程的实现。
主要的时序图:
Browser
CAW的Browser模块实现了CAW的大部分业务逻辑,包括对Content的封装调用,以及单进程渲染架构的实现。渲染的部分和对网络模块的封装在下面另外说明。
对Content的封装主要是对content API中Browser进程部分进行封装、实现,是作为一个Embedder必需的部分,涉及的类比较多,其中以AwContentBrowserClient为核心。(回顾一下AwMainDelegate那张类图。)
渲染
上面的数字已经说明了整个绘制过程。简化来看CAW的渲染基于Android View的onDraw()操作,再调回到Android View的ViewRoot。
以下为主要类图:
网络
主要类图如下:
AwNetworkDelegate在请求的Header中添加X-Requested-With来标识是当前包所发送的请求。
AwURLRequestContextGetter除了初始化网络上下文(包括指定Android特定scheme的解析器.),还会将BrowserThread指定为网络线程。
当有第一次获取URLRequestContext时就会触发创建创建过程,建立网络上下文环境。然后就可以基于它发起加载请求。如下图所示:
Android特别的schemes处理
上图中net::URLRequestInterceptingJobFactory使用层层嵌套的Job factory组成针不同schemes的解析链。如下图:
要点:
1. 实现了AndroidStreamReaderURLRequestJob支持以Java Stream的方法读取数据的请求。
2. AndroidRequestInterceptorBase实现任务控制,并在AwURLRequestContextGetter向网络层注册分别针对content:和asset (file:///android_asset/ and file:///android_res/ )的协议解释器。
CAW对Components的依赖