Chromium WebUI机制介绍

本文简要介绍一些Chromium WebUI的特点,然后分析其内部机制,最后介绍如何创建使用WebUI。

WebUI介绍

WebUI是通过本地的html网页来实现客户端的UI功能,把c++、html、css、js组织在一起,css,html做界面,js和c++做逻辑,灵活而又强大。chromium UI里面很多地方使用WebUI ,比如设置页面,flags开关页面,关于页面。我们在浏览器的地址栏中输入chrome://chrome-urls/,就可以看到更多的WebUI 链接页面。 chromium-webui

Chromium之所以大量用到WebUI,我想有两个主要原因:

WebUI机制分析

我们现在以chromium中一个简单而又典型WebUI页面chrome://version/为例子分析WebUI机制。

创建WebUI流程

在地址栏中输入chrome://version/与输入一个网址创建新标签页的基本流程是一致的。在地址栏中输入任何网址WebContentsImpl都会创建WebUIImpl 。如果在GetWebUIFactoryFunction中找到对应的chrome::kChromeUIVersionHost,就会创建对应的WebUIController——VersionUI,然后WebContentsImpl::CreateWebUI会判断WebUIController是否创建成功,如果创建失败则销毁WebUIImpl。 chromium-webui

资源加载流程

WebUI的资源加载也是复用一般的网页网络请求机制,不同的是一般的http协议底层是用URLRequestHttpJob去做网络请求,而WebUI则是使用URLRequestChromeJob。

在地址栏输入一个WebUI网址chrome://version/,就会创建VersionUI对象,VersionUI会创建一个与当前host绑定的WebUIDataSource,并添加到URLDataManager中。当发起网络请求,URLDataSourceImpl根据host返回对应的资源,然后再当做response返回。 chromium-webui

类图介绍

chromium-webui

ChromeWebUIControllerFactory是创建WebUI对应的WebUIController。

VersionUI实现了WebUIController,会根据WebUI的网址创建一个WebUIDataSource。WebUIDataSource就可以添加WebUI所需要的前端资源文件。VersionUI同时也创建VersionHandler并添加到WebUI中。

VersionHandler继承自WebUIMessageHandler。通过WebUI的RegisterMessageCallback来注册回调,VersionHandler就可以处理来自前端的js的调用。

其实VersionHandler并非必须要创建,任何类都可以通过WebUI来注册js回调函数。WebUI类就是用来连接js与c++交互的纽带。

c++与js交互

c++调用js非常简单,直接通过WebUI的CallJavascriptFunction来执行js代码中的函数,比如:

  base::StringValue arg(flash_version);
  web_ui()->CallJavascriptFunction("returnFlashVersion", arg);

CallJavascriptFunction底层其实是调用的通用的RenderFrameHost接口的ExecuteJavaScript。

Js调用c++稍微复杂一点。

首先browser进程中通过WebUI的RegisterMessageCallback来向js暴露自己可被调用的接口,实现对应接口处理函数。之后js就可以通过chrome.send方法去调用c++中的接口。

在renderer进程里面WebUIExtension::Install通过v8创建一个chrome的js对象,并暴露出send,getVariableValue两个接口,注册接口的c++回调函数。js直接调用chrome.send,然后在renderer进程中对应的回调函数通过IPC把函数调用相关的信息发送到browser进程中的WebUIImpl中。

前端资源

WebUI的前端html网页元素扩展了三个属性:i18n-content、i18n-options、i18n-values。

i18n-content可以用来指定元素的文本内容。比如我们在c++中指定application_label的字符串内容为Google Chrome,html网页写成,最终渲染出的html为Google Chrome。

i18n-options会生成一个